2015-11-16 21 views
7

Come posso scrivere un'aggregazione di termini Elasticsearch che divide i bucket per l'intero termine piuttosto che per i singoli token? Ad esempio, vorrei aggregare per stato, ma il seguente restituisce nuovo, York, jersey e California come singoli secchi, non New York e New Jersey e la California come i secchi come previsto:Aggregazione dei termini Elasticsearch per stringhe in un array

curl -XPOST "http://localhost:9200/my_index/_search" -d' 
{ 
    "aggs" : { 
     "states" : { 
      "terms" : { 
       "field" : "states", 
       "size": 10 
      } 
     } 
    } 
}' 

mio caso d'uso è come quello descritto qui https://www.elastic.co/guide/en/elasticsearch/guide/current/aggregations-and-analysis.html con una sola differenza: il campo città è un array nel mio caso.

Esempio oggetto:

{ 
    "states": ["New York", "New Jersey", "California"] 
} 

Sembra che la soluzione proposta (mappatura del campo come not_analyzed) non funziona per gli array.

mio mappatura:

{ 
    "properties": { 
     "states": { 
      "type":"object", 
      "fields": { 
       "raw": { 
        "type":"object", 
        "index":"not_analyzed" 
       } 
      } 
     } 
    } 
} 

ho cercato di sostituire "oggetto" da "string", ma questo non funziona neanche.

risposta

4

Penso che tutto quello che manca è "states.raw" nella vostra aggregazione (si noti che, dal momento che non è specificato alcun analizzatore, il campo "states" viene analizzato con la standard analyzer, il sub-campo "raw" è "not_analyzed"). Anche se la tua mappatura potrebbe portare anche a guardare. Quando ho provato la mappatura contro ES 2.0 ho ottenuto alcuni errori, ma questo ha funzionato:

PUT /test_index 
{ 
    "mappings": { 
     "doc": { 
     "properties": { 
      "states": { 
       "type": "string", 
       "fields": { 
        "raw": { 
        "type": "string", 
        "index": "not_analyzed" 
        } 
       } 
      } 
     } 
     } 
    } 
} 

poi ho aggiunto un paio di documenti:

POST /test_index/doc/_bulk 
{"index":{"_id":1}} 
{"states":["New York","New Jersey","California"]} 
{"index":{"_id":2}} 
{"states":["New York","North Carolina","North Dakota"]} 

E questa domanda sembra di fare ciò che si vuole:

POST /test_index/_search 
{ 
    "size": 0, 
    "aggs" : { 
     "states" : { 
      "terms" : { 
       "field" : "states.raw", 
       "size": 10 
      } 
     } 
    } 
} 

ritorno:

{ 
    "took": 1, 
    "timed_out": false, 
    "_shards": { 
     "total": 1, 
     "successful": 1, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 2, 
     "max_score": 0, 
     "hits": [] 
    }, 
    "aggregations": { 
     "states": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
      { 
       "key": "New York", 
       "doc_count": 2 
      }, 
      { 
       "key": "California", 
       "doc_count": 1 
      }, 
      { 
       "key": "New Jersey", 
       "doc_count": 1 
      }, 
      { 
       "key": "North Carolina", 
       "doc_count": 1 
      }, 
      { 
       "key": "North Dakota", 
       "doc_count": 1 
      } 
     ] 
     } 
    } 
} 

Ecco il codice che ho usato per provarlo:

http://sense.qbox.io/gist/31851c3cfee8c1896eb4b53bc1ddd39ae87b173e

+0

Grazie mille per la risposta, hai ragione, la mia domanda è infatti manca il '.raw'. Questo perché ho provato così tante diverse combinazioni di mappature e ricerche e ho finito per postarlo. La tua risposta mi ha portato a scoprire che il mio vero problema è che sto usando il plug-in elasticsearch-transport-couchbase per importare i miei documenti in Elasticsearch e il plugin cambia la struttura del documento, circondandolo con un attributo "doc". Grazie alla tua risposta, ho aggiunto un documento manualmente, e ha funzionato, ed è così che ho rilevato l'attributo "doc" circostante negli altri documenti. – Marieke