2016-01-18 7 views
5

Proszę, pomóżcie mi znaleźć mechanizm do agregacji w następującej domenie lub udowodnić, że nie istnieje w bieżącym API.Dołączenie agregacji reverse_nested w Elasticsearch

curl -XDELETE 127.0.0.1:9200/test_index 

    curl -XPUT 127.0.0.1:9200/test_index -d '{ 
     "mappings": { 
      "contact": { 
       "properties": { 
        "facebook_profile": { 
         "type": "nested", 
         "properties": { 
          "education": { 
           "type": "string" 
          }, 
          "year": { 
           "type": "integer" 
          } 
         } 
        }, 
        "google_profile": { 
         "type": "nested", 
         "properties": { 
          "education": { 
           "type": "string" 
          }, 
          "year": { 
           "type": "integer" 
          } 
         } 
        } 
       } 
      } 
     } 
    }' 

    curl -XPUT 127.0.0.1:9200/test_index/contact/contact1 -d '{ 
     "google_profile": { 
      "education": "stanford", "year": 1990 
     } 
    }' 

    curl -XPUT 127.0.0.1:9200/test_index/contact/contact2 -d ' 
    { 
     "facebook_profile": { 
      "education": "stanford", "year": 1990 
     } 
    }' 

W jaki sposób można wysłać zapytanie do ES, aby znaleźć statystyki dotyczące liczby kontaktów ukończył poszczególne uniwersytety?

znalazłem jedną możliwość, ale to nie daje mi pożądanego rezultatu, ponieważ nie może odpowiedzieć na pytanie powyżej w odniesieniu do kontaktów, ale tylko do ich indywidualnych profili (zagnieżdżone docs):

curl -XPOST '127.0.0.1:9200/test_index/_search?search_type=count&pretty=true' -d '{ 
     "aggs": { 
      "facebook_educations": { 
       "aggs": { 
        "field": { 
         "terms": { 
          "field": "contact.facebook_profile.education" 
         }, 
         "aggs": { 
          "reverse": { 
           "reverse_nested": { 
           } 
          } 
         } 
        } 
       }, 
       "nested": { 
        "path": "contact.facebook_profile" 
       } 
      }, 
      "google_educations": { 
       "aggs": { 
        "field": { 
         "terms": { 
          "field": "contact.google_profile.education" 
         }, 
         "aggs": { 
          "reverse": { 
           "reverse_nested": { 
           } 
          } 
         } 
        } 
       }, 
       "nested": { 
        "path": "contact.google_profile" 
       } 
      } 
     } 
    }' 

Co daje mi:

"aggregations" : { 
     "facebook_educations" : { 
      "doc_count" : 1, 
      "field" : { 
      "doc_count_error_upper_bound" : 0, 
      "sum_other_doc_count" : 0, 
      "buckets" : [ { 
       "key" : "stanford", 
       "doc_count" : 1, 
       "reverse" : { 
       "doc_count" : 1 
       } 
      } ] 
      } 
     }, 
     "google_educations" : { 
      "doc_count" : 1, 
      "field" : { 
      "doc_count_error_upper_bound" : 0, 
      "sum_other_doc_count" : 0, 
      "buckets" : [ { 
       "key" : "stanford", 
       "doc_count" : 1, 
       "reverse" : { 
       "doc_count" : 1 
       } 
      } ] 
      } 
     } 
    } 

Ale tu nie mogę być pewien, czy znaleziony kontakt jest taki sam lub inny dokument (rodzic), odpowiednio nie mogę odpowiedzieć na moje początkowe pytanie.

Dziękuję za radę.

Odpowiedz

0

Wygląda na to, że próbujesz uzyskać aggregate on multiple fields. Nie jest to obsługiwane bezpośrednio w Elasticsearch, ale istnieją sposoby na obejście tego problemu i uzyskanie oczekiwanych rezultatów.

Spójrz na discussion on Github, a także w documentation.

Jeśli dobrze rozumiem, czy "stanford" pojawia się w facebook_profile.education lub google_profile.education, chciałbyś, aby contact było liczone tylko raz w agregacji.

Powinieneś być w stanie to zrobić na jeden z dwóch sposobów:

  1. użyć skryptu do łączenia wartości przechowywane w polach:

    { 
        "aggs": { 
        "by_education": { 
         "terms": { 
         "script": "doc['contact.facebook_profile.education'].values + doc['contact.google_profile.education'].values" 
         } 
        } 
        } 
    } 
    
  2. Można utworzyć utworzyć nowy dedykowane pole w indeksie, które zawiera wartości z obu pól, przy użyciu opcji copy_to. Następnie agreguj na pojedynczym polu. Na przykład można skopiować zawartość obu pól do nowego pola o nazwie education_combined.

    { 
        "mappings":{ 
        "contact":{ 
         "properties":{ 
         "facebook_profile":{ 
          "type":"nested", 
          "properties":{ 
          "education":{ 
           "type":"string", 
           "copy_to":"education_combined" 
          }, 
          "year":{ 
           "type":"integer" 
          } 
          } 
         }, 
         "google_profile":{ 
          "type":"nested", 
          "properties":{ 
          "education":{ 
           "type":"string", 
           "copy_to":"education_combined" 
          }, 
          "year":{ 
           "type":"integer" 
          } 
          } 
         }, 
         "education_combined":{ 
          "type":"string" 
         } 
         } 
        } 
        } 
    } 
    

    Następnie wystarczy zsumować na education_combined:

    { 
        "aggs": { 
        "by_education": { 
         "terms": { "field": "education_combined" } 
        } 
        } 
    } 
    
+0

Twoja pierwsza sugestia po prostu nie działa, bo dla zagnieżdżonych docs masz dostęp do _source pole. Druga opcja może działać, ale niestety nie w moim przypadku, ponieważ mam zagnieżdżone dokumenty zawinięte w dokumentację potomną i próbuję wykonać jakąś agregację has_parent. Oto, co mam na razie http://stackoverflow.com/questions/35061945/match-query-inside-script-elasticsearch. Mimo wszystko dziekuję – Serj