2016-01-18 10 views
5

Please help me per trovare un meccanismo di aggregazione sul seguente dominio o per dimostrare che non esiste nell'API corrente.Join di aggregazioni reverse_nested in 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 
     } 
    }' 

Come si può interrogare ES per trovare statistiche su quanti dei contatti è laureato presso particolare le università?

ho trovato una possibilità, ma non mi dà risultato desiderato, dal momento che non può rispondere alla domanda di cui sopra per quanto riguarda i contatti, ma solo ai loro profili particolari (docs annidati):

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" 
       } 
      } 
     } 
    }' 

quello che mi dà:

"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 
       } 
      } ] 
      } 
     } 
    } 

Ma qui non posso essere sicuro se quello trovato contatto è uguale o diverso doc (genitore), rispettivamente, non posso rispondere alla mia domanda iniziale.

Grazie per qualsiasi consiglio.

risposta

0

Sembra che tu stia provando a aggregate on multiple fields. Questo non è supportato direttamente in Elasticsearch, ma ci sono modi per ovviare a questo e ottenere i risultati che stai cercando.

Dai uno sguardo allo discussion on Github e anche allo documentation.

Se sto capendo correttamente, se "stanford" appare in facebook_profile.education o google_profile.education, si desidera che lo contact venga conteggiato una sola volta nell'aggregazione.

Si dovrebbe essere in grado di fare questo in uno dei due modi:

  1. utilizzare uno script per concatenare i valori memorizzati nei campi:

    { 
        "aggs": { 
        "by_education": { 
         "terms": { 
         "script": "doc['contact.facebook_profile.education'].values + doc['contact.google_profile.education'].values" 
         } 
        } 
        } 
    } 
    
  2. è possibile creare creare un nuovo campo dedicato al tempo dell'indice che contiene i valori di entrambi i campi, utilizzando l'opzione copy_to. Quindi aggregare sul singolo campo. Ad esempio, è possibile copiare il contenuto di entrambi i campi in un nuovo campo denominato 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" 
         } 
         } 
        } 
        } 
    } 
    

    Quindi, è sufficiente aggregati sugli education_combined:

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

tuo primo suggerimento semplicemente non funziona, perché per documenti nidificati è necessario accedere sorgente_ campo. La seconda opzione potrebbe funzionare, ma sfortunatamente non nel mio caso, dal momento che ho i documenti annidati racchiusi in documenti figlio e sto cercando di eseguire una sorta di aggregazione has_parent. Questo è quello che ho per ora http://stackoverflow.com/questions/35061945/match-query-inside-script-elasticsearch. Grazie lo stesso – Serj

Problemi correlati