Настройка Elasticsearch для нечёткого поиска (Fuzzy Search)
Нечёткий поиск — это поиск с допуском на опечатки. Пользователь пишет «наутбук» вместо «ноутбук» или «javascipt» вместо «javascript» — запрос должен найти корректные результаты. Elasticsearch реализует нечёткость через метрику редакционного расстояния Левенштейна: количество односимвольных операций (вставка, удаление, замена, перестановка соседних символов) для превращения одной строки в другую.
Параметр fuzziness
fuzziness принимает три значения:
-
0— точное совпадение -
1— допускается 1 операция редактирования -
2— допускается 2 операции -
AUTO— автоматически: 0 для строк длиной 1–2, 1 для 3–5, 2 для 6+
AUTO — правильный выбор в большинстве случаев. fuzziness: 2 для коротких запросов даёт слишком много ложных совпадений.
Fuzzy запрос
POST /products/_search
{
"query": {
"fuzzy": {
"title": {
"value": "наутбук",
"fuzziness": "AUTO",
"prefix_length": 2,
"max_expansions": 50,
"transpositions": true
}
}
}
}
prefix_length: 2 — первые 2 символа должны совпадать точно. Критически важный параметр для производительности: без него fuzziness: 2 для однобуквенного запроса «а» теоретически совпадёт с огромным числом токенов. Устанавливайте минимум 1–2.
max_expansions: 50 — максимальное число вариантов, в которые расширяется нечёткий запрос. По умолчанию 50 — обычно достаточно.
transpositions: true — разрешить перестановки соседних символов (ab → ba). По умолчанию включено. Соответствует расстоянию Дамерау-Левенштейна.
Fuzzy в match запросе
Обычно нечёткость включается через match, а не через отдельный fuzzy:
POST /products/_search
{
"query": {
"match": {
"title": {
"query": "наутбук асус",
"fuzziness": "AUTO",
"prefix_length": 1,
"operator": "or",
"minimum_should_match": "75%"
}
}
}
}
match с fuzziness анализирует запрос (токенизирует, нормализует), потом применяет нечёткость к каждому токену. fuzzy запрос работает с сырым значением без анализа.
Multi-match с fuzziness
Для поиска по нескольким полям одновременно:
POST /products/_search
{
"query": {
"multi_match": {
"query": "асус наутбук",
"fields": ["title^3", "description", "brand^2"],
"type": "best_fields",
"fuzziness": "AUTO",
"prefix_length": 2
}
}
}
Буст через ^ — поле title в 3 раза важнее description, brand в 2 раза.
Комбинирование fuzzy с точным поиском
Лучший паттерн — запускать точный и нечёткий поиск параллельно, точные результаты должны занимать топ выдачи:
POST /products/_search
{
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "наутбук",
"fields": ["title^3", "description"],
"boost": 2
}
},
{
"multi_match": {
"query": "наутбук",
"fields": ["title^3", "description"],
"fuzziness": "AUTO",
"prefix_length": 2,
"boost": 1
}
}
]
}
}
}
Точное совпадение с бустом 2 будет выше нечёткого 1. Документы с точным совпадением поднимутся в топ, нечёткие окажутся ниже — но всё равно войдут в выдачу.
Phonetic анализ для фонетических опечаток
Fuzzy search покрывает орфографические ошибки, но не фонетические: «гугл» не найдёт «google» через fuzziness. Для этого — плагин analysis-phonetic.
Установка плагина:
/usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-phonetic
# перезапуск узла
Конфигурация анализатора с Metaphone (для английского):
"filter": {
"my_metaphone": {
"type": "phonetic",
"encoder": "double_metaphone",
"replace": false
}
},
"analyzer": {
"phonetic_analyzer": {
"tokenizer": "standard",
"filter": ["lowercase", "my_metaphone"]
}
}
"replace": false — сохранять оригинальный токен рядом с фонетическим. Так «google» будет найдено и по точному совпадению, и по фонетическому.
Для русского phonetic-энкодеры работают хуже — русская фонетика сложнее. Рекомендую комбинировать fuzziness: AUTO с ручным словарём синонимов для транслитераций.
Настройка relevance scoring
По умолчанию fuzzy результаты с расстоянием 2 получают score ниже, чем с расстоянием 1 или точные совпадения. Это поведение по умолчанию корректное. Если хочется явно управлять — function_score:
POST /products/_search
{
"query": {
"function_score": {
"query": {
"match": {
"title": {
"query": "наутбук",
"fuzziness": "AUTO"
}
}
},
"functions": [
{
"field_value_factor": {
"field": "popularity_score",
"factor": 1.5,
"modifier": "log1p",
"missing": 1
}
}
],
"boost_mode": "multiply"
}
}
}
Популярность товара (popularity_score) умножается на текстовую релевантность — популярные товары выходят выше при прочих равных.
Производительность
Fuzzy поиск дороже точного: на каждый токен строится список fuzzy-кандидатов через BK-tree. max_expansions и prefix_length — главные параметры для контроля нагрузки.
Для индексов с > 10 млн документов нечёткий поиск может замедляться. Решения: уменьшить max_expansions до 20–30, увеличить prefix_length до 3, добавить фильтры в bool.filter для сужения выборки перед fuzzy-частью запроса.
Сроки
Настройка нечёткого поиска с корректными параметрами fuzziness и тестирование на реальных данных — 1 рабочий день. Интеграция с phonetic-плагином и настройка для смешанной русско-английской базы — ещё 1 день.







