2015-03-12 16 views
17

devo alcuni documenti indicizzati su elasticsearch, guardando come questi campioni:Come ottenere gli ultimi valori per ogni gruppo con una query Elasticsearch?

{'country': 'France', 'collected': '2015-03-12', 'value': 20} 
{'country': 'Canada', 'collected': '2015-03-12', 'value': 21} 
{'country': 'Brazil', 'collected': '2015-03-12', 'value': 33} 
{'country': 'France', 'collected': '2015-02-01', 'value': 10} 
{'country': 'Canada', 'collected': '2015-02-01', 'value': 11} 
{'country': 'Mexico', 'collected': '2015-02-01', 'value': 9} 
... 

Voglio costruire una query che ottiene un risultato per ogni paese, ottenendo solo quelli con max(collected).

Quindi, per gli esempi mostrati sopra, i risultati sarebbero qualcosa come:

{'country': 'France', 'collected': '2015-03-12', 'value': 20} 
{'country': 'Canada', 'collected': '2015-03-12', 'value': 21} 
{'country': 'Brazil', 'collected': '2015-03-12', 'value': 33} 
{'country': 'Mexico', 'collected': '2015-02-01', 'value': 9} 

mi sono reso conto che ho bisogno di fare aggregazione su country, ma sto riuscendo a capire come limitare i risultati sul max(collected) .

Qualche idea?

risposta

28

è possibile utilizzare un'aggregazione top_hits che i gruppi sul campo country, restituisce 1 doc per gruppo, e ordina i documenti in base alla data discendente raccolti:

POST /test/_search?search_type=count 
{ 
    "aggs": { 
     "group": { 
      "terms": { 
       "field": "country" 
      }, 
      "aggs": { 
       "group_docs": { 
        "top_hits": { 
         "size": 1, 
         "sort": [ 
          { 
           "collected": { 
            "order": "desc" 
           } 
          } 
         ] 
        } 
       } 
      } 
     } 
    } 
} 
+0

Grazie, ho deciso di dargli un (Si noti l'uso del paese prime.) provare! – elias

+0

Ha funzionato bene, è intelligente - grazie! – elias

+0

Non hai ricevuto un errore del tipo: "I dati del campo sono disabilitati sui campi di testo per impostazione predefinita. Imposta fielddata = true su [paese] per caricare i dati del campo in memoria annullando l'inversione dell'indice. usa invece un campo di parole chiave? Se sì, come lo hai risolto? – user1892775

0

Per quelli come user1892775 che corrono in "Fielddata è disabilitato sui campi di testo per impostazione predefinita ... ", è possibile creare un campo multiplo (https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html). Così si potrebbe avere la mappatura del tipo:

"mapping": { 
    "properties": { 
     "country": {"type": "string", "fields": {"raw": {"type": "string", "index": "not_analyzed"}}} 
} 

Poi la query sarebbe simile

POST /test/_search?search_type=count 
{ 
    "aggs": { 
    "group": { 
     "terms": { 
      "field": "country.raw" 
     }, 
     "aggs": { 
      "group_docs": { 
       "top_hits": { 
        "size": 1, 
        "sort": [ 
         { 
          "collected": { 
           "order": "desc" 
          } 
         } 
        ] 
       } 
      } 
     } 
    } 
    } 
} 

Problemi correlati