2015-11-16 21 views
7

Jak mogę napisać agregację warunków Elasticsearch, która dzieli segmenty przez cały termin, a nie pojedyncze tokeny? Na przykład chciałbym agregowanie przez państwo, ale następujące powraca nowy, York, Jersey i Kalifornii jako indywidualne wiader, nie z Nowego Jorku i New Jersey i Kalifornii jak wiader zgodnie z oczekiwaniami:Elasticsearch terminy agregacja według ciągów w tablicy

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

Mój przypadek użycia jest podobny do opisanego tutaj https://www.elastic.co/guide/en/elasticsearch/guide/current/aggregations-and-analysis.html z jedną różnicą: Pole miasta jest tablicą w moim przypadku.

Przykład Obiekt

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

Wydaje się, że zaproponowane rozwiązanie (mapowanie boiska not_analyzed) nie działa w tablicach.

Moje mapowania:

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

Próbowałem zastąpić "obiekt" przez "string", ale to nie działa albo.

Odpowiedz

4

myślę wszystko tracisz jest "states.raw" w agregacji (należy pamiętać, że ponieważ nie analizator jest określony, pole "states" jest analizowany z standard analyzer; sub-field "raw" jest "not_analyzed"). Chociaż twoje mapowanie również może wyglądać. Kiedy próbowałem swoje odwzorowanie przeciwko ES 2.0 Mam kilka błędów, ale to działało:

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

Potem dodałam kilka dokumentów:

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

I to zapytanie wydaje się robić to, co chcesz:

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

powrocie:

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

Oto kod użyłem go przetestować:

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

+0

Dziękuję bardzo za odpowiedź, masz rację, moje pytanie jest rzeczywiście brakuje '.raw'. To dlatego, że wypróbowałem tak wiele różnych kombinacji mapowań i wyszukiwań, a ostatecznie opublikowałem tę. Twoja odpowiedź doprowadziła mnie do wykrycia, że ​​moim prawdziwym problemem jest to, że używam wtyczki elasticsearch-transport-couchbase do importowania moich dokumentów do Elasticsearch, a wtyczka zmienia strukturę mojego dokumentu, otaczając go atrybutem "doc". Dzięki Twojej odpowiedzi dodałem dokument ręcznie i zadziałało, i tak odkryłem otaczający atrybut "doc" w innych dokumentach. – Marieke