Экранирование зарезервированных слов в Elasticsearch

Гайд по экранированию зарезервированных символов в Elasticsearch. Ищите плюсы, минусы и операторы как профи — без ошибок и головной боли.

Дата актуализации: .


При работе с Elasticsearch часто возникает необходимость искать документы, содержащие слова, которые одновременно являются зарезервированными символами или ключевыми словами языка запросов (например, AND, OR, NOT, +, -, !, ~, *, ?, :, , /, (, ), {, }, [, ], "). Если такие слова встречаются в индексируемом тексте как обычные термины, их нужно искать точно так же, как и любые другие слова, но без учёта их специального значения в синтаксисе запроса. Для этого применяются кавычки («» или “”) – они переводят содержимое в фразовый запрос и отключают обработку зарезервированных символов.

Почему кавычки важны?

  • Отключение синтаксиса query_string. Внутри двойных кавычек Elasticsearch воспринимает всё как одну фразу и не пытается разбирать её на операторы.
  • Точное совпадение. Кавычки гарантируют, что будет найден документ, содержащий именно эту последовательность токенов в том же порядке.
  • Поддержка регистронезависимого поиска. При использовании стандартных анализаторов (например, standard или russian) внутри кавычек всё равно применяется токенизация и фильтрация, поэтому поиск остаётся нечувствительным к регистру и к stemming.

Основные способы экранирования зарезервированных слов

Query String с двойными кавычками

Самый простой способ – использовать запрос типа query_string и заключить искомое слово в двойные кавычки.

GET /my_index/_search
{
 "query": {
 "query_string": {
 "query": ""AND"",
 "default_field": "name"
 }
 }
}

В данном примере будет найден любой документ, поле name которого содержит токен and (после применения анализатора russian или standard он будет приведён к нижнему регистру).

Match Phrase

Если вам не нужен полный синтаксис query_string, можно воспользоваться запросом match_phrase. Он также обрабатывает фразу как единое целое и не требует экранирования специальных символов.

GET /my_index/_search
{
 "query": {
 "match_phrase": {
 "name": "AND"
 }
 }
}

Term‑level запрос (keyword поле)

Когда поле объявлено как keyword (не анализируется), достаточно точного совпадения без кавычек, но если в значении присутствуют зарезервированные символы, их всё же нужно экранировать в самом значении:

GET /my_index/_search
{
 "query": {
 "term": {
 "name.raw": ""AND""
 }
 }
}

Здесь мы ищем точное значение "AND" (включая кавычки) в неанализированном поле name.raw. Если нужно найти слово без кавычек, просто указываем AND.

Примеры с русским анализатором

Допустим, у нас есть индекс test_search с маппингом из вопроса:

PUT /test_search
{
 "mappings": {
 "first_test": {
 "properties": {
 "number": { "type": "keyword" },
 "name": {
 "type": "text",

 "analyzer": "russian",
 "fields": {
 "raw": { "type": "keyword" }
 }
 }
 }
 }
 }
}

Индексируем несколько документов:

POST /test_search/first_test/_bulk
{ "index": { "_id": 1 } }
{ "name": "В этом документе есть слово AND" }
{ "index": { "_id": 2 } }
{ "name": "Здесь AND используется как оператор" }
{ "index": { "_id": 3 } }
{ "name": "Нет такого слова" }

Поиск зарезервированного слова AND

GET /test_search/first_test/_search
{
 "query": {
 "query_string": {
 "query": ""AND"",
 "default_field": "name"
 } }
}

Результат: документы с _id 1 и 2, потому что оба содержат токен and после применения русского анализатора (приведение к нижнему регистру, удаление стоп‑слов не затрагивает and).

Поиск фразы с несколькими зарезервированными словами

Нужно найти документы, где встречается фраза AND OR NOT:

GET /test_search/first_test/_search
{
 "query": {
 "match_phrase": {
 "name": "AND OR NOT"
 }
 }
}

Если таких документов нет, запрос вернёт пустой результат.

Частые ошибки и как их избегать

  • Забывание про регистр. В query_string внутри кавычек регистр всё равно нормализуется анализатором. Если вы используете keyword поле без анализатора, то "And" и "and" будут различаться.
  • Экранирование обратным слешем вместо кавычек. Обратный слеш () экранирует отдельный символ, но не отменяет синтаксис операторов. Для полного отключения нужны кавычки.
  • Использование одинарных кавычек. В Elasticsearch одинарные кавычки не имеют специального значения в query_string; они воспринимаются как обычные символы. Поэтому для фразового поиска нужны именно двойные кавычки.
  • Смешивание анализируемых и неанализируемых полей. Если вы ищете в keyword поле, но всё равно ставите кавычки, ищите буквально кавычки как часть термина. Убедитесь, что выбран правильный тип поля.

Рекомендации по использованию

  1. Для полнотекстового поиска зарезервированных слов предпочтительно использовать match_phrase или query_string с двойными кавычками.
  2. Если поле не анализируется (keyword) и вам нужно точное совпадение, используйте term без кавычек (или с кавычками, если они действительно часть значения).
  3. При составлении сложных булевых выражений выносите зарезервированные слова в отдельные query_string‑подзапросы, заключая каждое в кавычки, чтобы избежать неоднозначности.
  4. Тестируйте запросы через _analyze API, чтобы увидеть, как анализатор преобразует ваш запрос:
GET /test_search/_analyze
{
 "analyzer": "russian",
 "text": ""AND""
}

Вы увидите, что токен and производится без кавычек, подтверждая, что кавычки работают как группирующий оператор.

Кавычки в Elasticsearch – простой и надёжный способ искать зарезервированные слова и символы, лишая их специального значения в синтаксисе запросов; Независимо от того, используете ли вы полнотекстовый (match_phrase, query_string) или терм‑уровневый (term) поиск, правильное применение кавычек гарантирует, что вы получите именно те документы, которые содержат нужный термин в точном виде, независимо от его служебного значения в языке запросов.

Помните: всегда проверяйте, как ваш запрос преобразуется анализатором (через _analyze), и тестируйте на небольшом наборе данных перед запуском в production. Это избавит от неприятных сюрпризов и сделает ваш поиск предсказуемым и эффективным.