Анализаторы и токенизация
Разбираем, как именно текст превращается в термы инвертированного индекса — то есть устройство анализатора.
Анализатор — конвейер, превращающий строку текста в набор термов; состоит из символьных фильтров, токенизатора и токен-фильтров.
Зачем
Чтобы match находил «Кофемашины» по запросу «кофемашина», текст и запрос должны проходить одинаковую обработку: разбиение на слова, нижний регистр, обрезка до основы. Эту обработку и выполняет анализатор — и при индексации, и при поиске.
Конвейер из трёх ступеней
"Кофе, КОФЕ и чай!"
|
[1] char filter -- убрать/заменить символы (напр. HTML)
|
"Кофе, КОФЕ и чай!"
|
[2] tokenizer -- разбить на токены по границам слов
|
[Кофе] [КОФЕ] [и] [чай]
|
[3] token filters -- нижний регистр, убрать стоп-слова, стемминг
|
[кофе] [кофе] [чай] --> в индекс| Ступень | Что делает |
| char filter | правит сырой текст до разбиения (например, выкидывает HTML-теги) |
| tokenizer | режет текст на токены (обычно по пробелам и пунктуации) |
| token filters | преобразуют токены: нижний регистр, стоп-слова, стемминг, синонимы |
Готовые анализаторы
Не нужно собирать конвейер с нуля — есть встроенные:
standard— по умолчанию: режет по словам, нижний регистр, базовая обработка пунктуации;simple— режет по любым не-буквам, нижний регистр;keyword— не режет вовсе, весь текст — один токен (для точных полей);russian,englishи др. — языковые: добавляют стоп-слова и стемминг для конкретного языка.
Проверить анализатор: _analyze
Лучший способ понять, что попадёт в индекс — спросить ES напрямую:
curl -X POST http://localhost:9200/_analyze \
-H 'Content-Type: application/json' \
-d '{ "analyzer": "standard", "text": "Кофе, КОФЕ и чай!" }'В ответе вы увидите итоговые токены с их позициями. Этим инструментом стоит пользоваться постоянно при отладке поиска.
Как работает под капотом
При индексации поля text ES прогоняет его значение через анализатор поля и кладёт получившиеся термы в инвертированный индекс. При поиске match прогоняет строку запроса через тот же анализатор. Совпадение происходит на уровне термов: важно не как выглядел исходный текст, а какие термы из него получились. Поэтому ответ на вопрос «почему не находит» почти всегда лежит в том, какие термы реально лежат в индексе — а это показывает _analyze.
Частые ошибки
- Разные анализаторы при индексации и поиске. Если поле проиндексировано одним анализатором, а ищется другим, термы не совпадут. По умолчанию ES использует один и тот же — не ломайте это без причины.
- Анализатор по умолчанию для русского.
standardне делает стемминг русского, поэтому «кофемашины» и «кофемашина» — разные термы. Для русского нужен анализаторrussian.
Итоги
- Анализатор — конвейер: символьные фильтры → токенизатор → токен-фильтры.
- Один и тот же анализатор применяется при индексации и при поиске; совпадение идёт по термам.
- Эндпоинт
_analyzeпоказывает, какие термы получаются — главный инструмент отладки.