Поле text индексируется в виде проанализированных терминов. Наш standard analyzer разбивает текст на токены и приводит к нижнему регистру. Запросы вроде match анализируют и входную строку, поэтому один регистр обычно не мешает совпадению. Это отличается от точного keyword-поиска. В тренажёре анализатор фиксирован; реальные проекты могут иметь другую обработку языка и синонимов.
Полнотекстовый поиск не является поиском произвольной подстроки. Рассуждайте о словах, позициях и допустимых правках. Разные запросы могут показать одну страницу, но по-разному работать на других документах. Сначала выберите тип запроса по условию, затем настраивайте релевантность.
- Вход: TRAVEL Speaker
- Разбить на токены
- Нижний регистр: travel, speaker
- Сопоставить с терминами индекса
Индексируемый текст и вход match анализируются. Keyword-значения идут по отдельному пути точного совпадения.
Примеры выполнены на публичном наборе products в Elasticsearch 9.4.3. Ответы — сокращённые фрагменты JSON: время, сведения о шардах и индексе опущены. Числовые оценки иллюстративны и могут меняться. Примеры объясняют способ решения; значения в заданиях могут отличаться.
Поиск по тексту
match — отправная точка поиска по text. Вход TRAVEL анализируется и может совпасть с Travel в name. Результат определяется терминами, а не сравнением исходной JSON-строки с учётом регистра. Оценка характеризует совпадение в текущем корпусе, а не процент уверенности.
Для нескольких входных слов по умолчанию действует operator or: может хватить одного проанализированного слова. Это полезно для широкого поиска, но не означает обязательность всех слов или совпадение фразы. Следующие разделы задают эти требования явно.
Разберём другой сценарий
{
"query": {
"match": {
"name": "TRAVEL"
}
},
"size": 2,
"_source": [
"name",
"price"
]
}Ответ Elasticsearch
{
"hits": {
"total": {
"value": 60,
"relation": "eq"
},
"hits": [
{
"_id": "3",
"_score": 1.6332386,
"_source": {
"name": "Sony Travel Speaker 3",
"price": 100
}
},
{
"_id": "13",
"_score": 1.6332386,
"_source": {
"name": "Apple Travel Speaker 13",
"price": 100
}
}
]
}
}Как читать результат
Названия содержат проанализированный термин travel, несмотря на верхний регистр входа. Сравните это с регистрозависимым term по keyword.
Поиск фразы
match_phrase учитывает позиции токенов наряду с терминами. При slop по умолчанию, равном нулю, слова должны стоять рядом и в том же порядке. Пример ищет gaming keyboard; название с keyboard перед gaming является другой фразой, хотя содержит оба слова.
Поиск фразы также анализирует текст. Он не требует равенства всего поля фразе: длинное название может содержать её внутри последовательности токенов. Точное равенство всей строки относится к подходящему keyword-полю, а не к match_phrase.
- gaming + keyboard
- Gaming Keyboard: фраза + И
- Keyboard for Gaming: только И
Одна пара токенов может пройти поиск И, но не точную фразу.
Разберём другой сценарий
{
"query": {
"match_phrase": {
"name": "gaming keyboard"
}
},
"size": 2,
"_source": [
"name",
"price"
]
}Ответ Elasticsearch
{
"hits": {
"total": {
"value": 30,
"relation": "eq"
},
"hits": [
{
"_id": "4",
"_score": 4.6608744,
"_source": {
"name": "Logitech Gaming Keyboard 4",
"price": 199
}
},
{
"_id": "14",
"_score": 4.6608744,
"_source": {
"name": "Samsung Gaming Keyboard 14",
"price": 199
}
}
]
}
}Как читать результат
Фраза встречается в том же порядке в подходящих названиях. Дополнительные слова до или после неё не мешают совпадению.
Поиск по нескольким полям
multi_match применяет текстовый запрос к явно перечисленным полям. Поиск по name и description находит товар, даже если нужная формулировка есть только в описании. Стратегия best_fields по умолчанию определяет релевантность по лучшему полю, а не просто добавляет по баллу за каждое совпадение.
Названия полей указываются в массиве fields. Значения анализируются по mapping каждого поля. Тренажёр требует явный разрешённый список, поэтому wildcard в селекторе полей использовать не нужно. Возвращаемые поля _source не определяют поля поиска.
Разберём другой сценарий
{
"query": {
"multi_match": {
"query": "gaming",
"fields": [
"name",
"description"
]
}
},
"size": 2,
"_source": [
"name",
"description"
]
}Ответ Elasticsearch
{
"hits": {
"total": {
"value": 30,
"relation": "eq"
},
"hits": [
{
"_id": "4",
"_score": 2.3304372,
"_source": {
"name": "Logitech Gaming Keyboard 4",
"description": "Reliable everyday accessory"
}
},
{
"_id": "14",
"_score": 2.3304372,
"_source": {
"name": "Samsung Gaming Keyboard 14",
"description": "Travel companion with long battery life"
}
}
]
}
}Как читать результат
Просмотрите оба текстовых поля, чтобы найти причину совпадения. Отсутствие слова только в name ещё не означает ошибочный результат.
Все слова обязательны
Объект match может содержать query и operator. Значение operator: and требует каждый проанализированный термин в одном поле. В примере travel и speaker должны встречаться в name. Соседство не требуется; это также не равенство строки полному названию товара.
Не путайте И между терминами с bool.must между разными запросами. Оба задают совместное выполнение, но на разных уровнях. Если задача требует все слова в одном поле, match с operator and прямо выражает это намерение.
Разберём другой сценарий
{
"query": {
"match": {
"name": {
"query": "travel speaker",
"operator": "and"
}
}
},
"size": 2,
"_source": [
"name",
"price"
]
}Ответ Elasticsearch
{
"hits": {
"total": {
"value": 30,
"relation": "eq"
},
"hits": [
{
"_id": "3",
"_score": 3.9636757,
"_source": {
"name": "Sony Travel Speaker 3",
"price": 100
}
},
{
"_id": "13",
"_score": 3.9636757,
"_source": {
"name": "Apple Travel Speaker 13",
"price": 100
}
}
]
}
}Как читать результат
Название только с travel или только со speaker исключается. Сравните total с более широким вариантом OR по умолчанию.
Поиск с опечаткой
Fuzziness допускает ограниченное число правок между проанализированным термином запроса и термином индекса. AUTO выбирает расстояние по длине слова и не означает произвольное сходство. В примере travle может совпасть с travel за счёт перестановки. Это инструмент для опечаток, а не замена точных идентификаторов и бизнес-фильтров.
Нечёткий запрос всё ещё работает с анализируемыми словами. Он не является wildcard для произвольной подстроки. Более свободный поиск может добавить лишние документы, поэтому включайте fuzziness, когда требуется допуск опечаток. В тренажёре дорогие scripts, wildcard и regexp намеренно недоступны.
Разберём другой сценарий
{
"query": {
"match": {
"name": {
"query": "travle",
"fuzziness": "AUTO"
}
}
},
"size": 2,
"_source": [
"name",
"price"
]
}Ответ Elasticsearch
{
"hits": {
"total": {
"value": 60,
"relation": "eq"
},
"hits": [
{
"_id": "3",
"_score": 1.3610321,
"_source": {
"name": "Sony Travel Speaker 3",
"price": 100
}
},
{
"_id": "13",
"_score": 1.3610321,
"_source": {
"name": "Apple Travel Speaker 13",
"price": 100
}
}
]
}
}Как читать результат
В названиях используется правильное travel, а не опечатка. Ответ демонстрирует ограниченное исправление токена, а не поиск подстроки.
Краткая памятка
- match анализирует вход; term — нет.
- match_phrase требует позиции и порядок, а не равенство всего поля.
- multi_match явно перечисляет поля поиска.
- operator and требует все проанализированные слова в поле match.
- AUTO допускает ограниченные правки, а не произвольные шаблоны.
Официальная документация
Готовы применить знания?
Подтвердите прочтение, чтобы сохранить своё место. Чтение и решение заданий учитываются отдельно в этом браузере с помощью гостевой cookie.