Страницы

Поиск по вопросам

понедельник, 17 декабря 2018 г.

Неправильно работает поиск в Elasticsearch

Установил elastic. Настроил индексацию. Но в запросах какая-то странность выходит. Никак не пойму почему поиск некорректно работает
Я делал запросы с помощью либы в ruby, и пенял на нее, однако когда отснифал запрос понял что тут проблема в самом elastic. Да это даже не проблема, скорее фича.
prod = Post.search "ра", fields: [:title] // На выходе n-элементов prod = Post.search "разд", fields: [:title] // На выходе 0-элементов prod = Post.search "раздел", fields: [:title] // На выходе n-элементов
Скорее всего где то надо найти настройку, которая позволит улучшить поиск.


Ответ

Скорее всего, это поведение анализатора. ES использует немного более сложную схему поиска, нежели привычное точное совпадение:
При загрузке документа все текстовые поля пропускаются через анализатор, состоящий из токенайзера и фильтров Токенайзер бьет ввод на отдельные токены (как правило, это слова) Фильтры изменяют, добавляют и удаляют токены Токены записываются в конечный индекс При поиске запрос снова пропускается через анализатор, бьется на токены, и ES ищет совпадения между токенами запроса и токенами документа
Я подозреваю, что проблема именно в этом - в ES существуют токены "ра" и "раздел", но не существует токена "разд".
Скорее всего, дело именно в том, на какие токены разбивается запрос при поиске текущим анализатором. Чтобы проверить это, необходимо просмотреть токены совпадающих документов и токены запроса:
curl -XGET :9200//_analyze -d '{ "text": "разд" }'
curl -XGET :9200//_analyze -d '{ "text": "раздел" }'
curl -XGET :9200//_analyze -d '{ "text": "<текст документа>" }'
* В случае, если при поиске используется анализатор, отличный от анализатора индекса по умолчанию - скорее всего, вопрос это не подразумевает - его можно указать в поле "analyzer" * Токены документов можно получить напрямую из elasticsearch, но это немного сложнее
Если вы использовали все настройки по умолчанию, то у вас стоит стандартный анализатор, который (во всяком случае, у меня) даст следующие результаты:
Ра Разд Раздел
(причем я смог добиться поиска по последним двум запросам, но даже при ненормально больших fuzziness ES отказася находить мне что-либо по "ра", что подталкивает к тому, что либо у вас все-таки нестандартный анализатор, либо я полностью забыл эластик)
После этого вы можете посмотреть, как именно совпадает или не совпадает документ, с помощью explain API:
curl -XGET :9200////_explain -d '{ "query": { "query_string" : { "query": "ра" } } }'
* непосредственно запрос может отличаться и зависит от вашей библиотеки
Таким образом вы сможете найти причину этого поведения самостоятельно - со стороны коммьюнити это почти невозможно, пока вы не привели mapping соответствующего индекса в ES, документы, которые совпадает по двум из трех запросов, непосредственно сам запрос, который передает библиотека и версию ES. Однако, насколько я понимаю, конкретно за этим вопросом стоит необходимость сделать автокомплит - в этом случае вам нужен не поиск внутри ES, а suggester completion - это немного другой функционал ES, который создан именно для реализации автокомплита.

Комментариев нет:

Отправить комментарий