Эластичная поисковая группа по полям

У меня есть следующие данные в моем файле index.

{
"id":1,
"car_name" : "ABC-101"
},
{
"id":2,
"car_name" : "DEF-102"
},
{
"id":3,
"car_name" : "ABC-103"
}

Отображение моего индекса

{
  "car": {
    "mappings": {
      "_doc": {
        "properties": {
          "car_name": {
            "type": "text",
            "fielddata": true
          }
        }
      }
    }
  } 
}

Почему я запускаю следующий запрос

 localhost:9200/car/_doc/_search?pretty

Со следующим телом запроса

{
"size" : 0,
"aggs" : {
    "genres" : {
        "terms" : { 
            "field" : "car_name"
        }
    }
}

}

получаю следующий ответ

"buckets": [
    {
      "key": "ABC",
      "doc_count": 2
    },
    {
      "key": "DEF",
      "doc_count": 1
    },
    {
      "key": "101",
      "doc_count": 1
    },
    {
      "key": "102",
      "doc_count": 1
    },
    {
      "key": "103",
      "doc_count": 1
    }
]

Почему не приведены фактические ключи ABC-101 и DEF-102, почему ABC и 101 рассматриваются как отдельные ключи.


person user4906240    schedule 07.10.2019    source источник
comment
Можете ли вы также показать свое отображение индекса, пожалуйста?   -  person Val    schedule 07.10.2019
comment
Должна быть проблема с токеном. elastic.co/guide/en/ elasticsearch/reference/current/ , например generate_word_parts   -  person LeBigCat    schedule 07.10.2019


Ответы (1)


По умолчанию строковые поля имеют значение analyzed в elasticsearch. Это означает, что ABC-101 индексируется как 2 термина ABC и 101. Ваш запрос также анализируется и преобразуется в 2 термина ABC и 101 независимо от того, какие специальные символы находятся между ними.

Вот почему они соответствуют всем строкам, разделенным -, например ABC, 101, DEF, 102 и т. д.

e.g

  {
  "car": {
    "car_name": "string",
    "fields": {
      "raw": {
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }  
  }

Если вы хотите искать это поле точно так, как оно есть, вы должны переиндексировать его как "index":"not_analyzed"

Вы можете заставить его работать с keyword в поле car_name, чтобы точно соответствовать

{
  "size" : 0,
  "aggs" : {
      "genres" : {
          "terms" : { 
              "field" : "car_name.keyword"
          }
      }
  }
person Always Sunny    schedule 07.10.2019
comment
Использование типа keyword является текущей лучшей практикой, not_analyzed string осталось в прошлом. - person Val; 07.10.2019
comment
В итоге я использовал тип ключевого слова, и теперь я получаю желаемый результат. Я не знаю, почему, когда я использовал текстовое поле, я не мог использовать field.keyword в своей агрегации. - person user4906240; 07.10.2019
comment
Потому что в вашем отображении не было подполя keyword. - person Val; 07.10.2019