Агрегация терминов ElasticSearch по всему полю

Как я могу написать запрос агрегации термина ElasticSearch, который учитывает все значение поля, а не отдельные токены? Например, я хотел бы агрегировать по имени города, но следующее возвращает new, york, san и francisco как отдельные ведра, а не new york и san francisco в качестве ковшей, как ожидалось.

curl -XPOST "http://localhost:9200/cities/_search" -d'
{
   "size": 0, 
   "aggs" : {
     "cities" : {
         "terms" : { 
            "field" : "city",
            "min_doc_count": 10
         }
     }
   }
}'

Ответ 1

Вы должны исправить это в своем сопоставлении. Добавьте поле not_analyzed. Вы можете создать многопользовательское поле, если вам также нужна анализируемая версия.

"album": {
  "city": "string",
  "fields": {
    "raw": {
      "type": "string",
      "index": "not_analyzed"
    }
  }
}

Теперь создайте свой агрегат на city.raw

Ответ 2

Этот эластичный документ предлагает исправить это при сопоставлении (как предлагается в принятом ответе) - либо сделать поле not_analyzed, либо добавьте необработанное поле с not_analyzed и используйте его в агрегатах.

Нет другого пути для этого. Поскольку агрегирования работают с инвертированным индексом, и если поле анализируется, инвертированный индекс должен иметь только токены, а не исходные значения поля.

Ответ 3

теперь мы можем использовать синтаксис .keyword после сгруппировки по полю в соответствии с this

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}