Поиск в Elasticsearch: игнорирование специальных символов и буквальные запросы

Узнайте, как настроить Elasticsearch для игнорирования спецсимволов и использования буквальных запросов. Точный поиск фраз с пунктуацией — просто и эффективно!

В данной статье мы рассмотрим‚ как эффективно выполнять поиск в системах полнотекстового индексирования (например‚ Elasticsearch) когда в запросе необходимо игнорировать специальные символы‚ а также как использовать буквальные (цитируемые) запросы для точного совпадения фраз‚ содержащих пунктуацию. Тема статьи взята из условного заголовка «50 лет октября‚ 50 кв 40 дана гадалка»‚ который служит лишь отправной точкой для обсуждения технических аспектов поиска.


Почему специальные символы создают проблемы?

При индексации текста большинство поисковых движков выполняют токенизацию: разбивают исходную строку на отдельные токены‚ удаляя при этом знаки препинания‚ дефисы‚ слэши и другие «шумовые» символы. Это делается для ускорения поиска и уменьшения размера индекса. Однако иногда пользователь хочет найти документ‚ где эти символы присутствуют именно в том виде‚ в котором он их ввёл (например‚ номер документа 8652 / 58996-3). Если просто передать в запрос строку 8652589963‚ стандартный анализатор не найдёт совпадения‚ потому что токены будут отличаться.

Как выполнить query_string поиск‚ игнорируя специальные символы

В Elasticsearch существует несколько подходов:

  1. Использовать пользовательский анализатор‚ который сохраняет цифры и буквы‚ но удаляет пунктуацию при индексировании и при запросе.
  2. Применять query_string с регулярными выражениями‚ позволяющими задать шаблон‚ игнорирующий нежелательные символы.
  3. Выполнять предварительную очистку входного значения (удаление пробелов‚ дефисов‚ слэшей) и искать по очищенному полю.

Пример пользовательского анализатора:

PUT my_index
{
 "settings": {
 "analysis": {
 "analyzer": {
 "digit_analyzer": {
 "tokenizer": "keyword"‚
 "filter": ["lowercase"‚ "asciifolding"]
 }
 }

 }
 }‚
 "mappings": {
 "properties": {
 "refNo": {
 "type": "text"‚
 "analyzer": "digit_analyzer"
 }
 }
 }
}

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

Буквальные (цитируемые) запросы

Если необходимо найти точное совпадение фразы‚ включая знаки препинания‚ следует использовать цитируемый запрос (заключённый в двойные кавычки). В Elasticsearch это делается через query_string с оператором " ":

GET my_index/_search
{
 "query": {
 "query_string": {
 "query": ""8652 / 58996-3""‚
 "default_field": "refNo"
 }
 }
}

Важно: при использовании стандартного анализатора кавычки не сохраняются в индексе‚ поэтому для буквального поиска часто создают отдельное поле с keyword-типом (не анализируемым). Пример:

"mappings": {
 "properties": {
 "refNo": { "type": "text" }‚
 "refNoExact": { "type": "keyword" }
 }
}

Тогда запрос выглядит так:

GET my_index/_search
{
 "query": {
 "term": {
 "refNoExact": "8652 / 58996-3"
 }
 }}

Практические рекомендации

  • Определите‚ нужны ли вам специальные символы в поиске. Если они лишь шум – используйте анализатор‚ удаляющий их.
  • Для точного совпадения фраз с пунктуацией создайте отдельное keyword-поле. Это гарантирует‚ что запрос с кавычками вернёт именно те документы‚ где фраза встречается без изменений.
  • Тестируйте анализаторы с помощью API _analyze‚ чтобы увидеть‚ как преобразуются ваши входные строки.
  • Не забывайте про производительность. Регулярные выражения в query_string могут быть дорогими; предпочтительнее использовать подготовленные поля.

Поиск в полнотекстовых системах требует понимания того‚ как обрабатываются специальные символы и пунктуация. Выбирая правильный анализатор‚ создавая дополнительные keyword-поля и используя цитируемые запросы‚ можно достичь как гибкого‚ так и точного поиска. Надеемся‚ представленные примеры и рекомендации помогут вам эффективно работать с данными‚ содержащими спецсимволы‚ будь то номера документов‚ коды продуктов или любые другие строки‚ где важна каждая деталь.