ElasticSearch: поиск по bool/терминам НЕ зависит от регистра

#elasticsearch

Вопрос:

Следующий запрос ElasticSearch дает ожидаемый результат:

 {'query': {'bool': {'must': [{'bool': {'should': [{'term': {'name.keyword': 'Finding'}}]}}]}}, 'size': 10, 'from': 0}
 

но этот дает пустой результат.

 {'query': {'bool': {'must': [{'bool': {'should': [{'term': {'name.keyword': 'finding'}}]}}]}}, 'size': 10, 'from': 0}
 

Единственное отличие состояло в том, что «Найти» изменилось на «найти». ElasticSearch по умолчанию «не учитывает регистр», и у меня есть следующее сопоставление. Я ожидал, что оба запроса дадут мне один и тот же результат. Что здесь не так?

   "name": {
    "type": "text",
    "analyzer": "keyword",
    "fields": {
      "keyword": {
        "type": "keyword",
        "ignore_above": 256
      }
    }
  
 

Ответ №1:

Запрос термина возвращает точные документы, содержащиеся в поле. Он не анализирует искомый термин.

  1. В первом случае вы используете анализатор ключевых слов ( name.keyword ). Это будет обозначено как . Finding Finding Поэтому , когда вы используете запрос термина для поиска Finding , это вернет вам документ, содержащий точный термин Finding
  2. Во втором случае вы запрашиваете name поле. Elasticsearch использует стандартный анализатор, если анализатор не указан. Итак, здесь Finding будет finding обозначено .

Теперь, если вы выполните поиск по finding запросу с использованием термина, вы не получите никакого результата поиска. Поскольку в индексе нет документа, содержащего документ, содержащий "name":"finding"


С 7.10 elasticsearch ввел новый параметр case_insensitive , который позволяет нам выполнять поиск без учета регистра.

 {
  "query": {
    "term": {
      "name.keyword": {
        "value": "finding",
        "case_insensitive": true
      }
    }
  }
}
 

Если вы используете версию Elasticsearch ниже 7.10.0, то вам следует использовать запрос соответствия для полнотекстового поиска