В своих проектах часто использую Django Haystack для поиска, в качестве бекэнда выступает Elasticsearch. К сожалению, Haystack предоставляет довольно мало возможностей для настройки индексов, все они вшиты в код. Из-за чего стречаются малкие и серьезные проблемы. С одной из таких проблем столкнулся, когда нужно было реализовать поиск с автодополнением (autocomplete).
Обратимся к документации:
Сказано, что при поиске строки old, мы получим слудуюшие результаты:
goldfish, cuckold и older
Все хорошо, пока мы не включили в поиск слово длиннее трех символов. При поиске строки gold, результаты будут неожиданными:
goldfish, cuckold, older, golrang, golf
То есть в поисковую выдачу попадут слова включающе любые три символа в поисковом запросе. Причина этому дефольные настройки Elasticsearch, которые прадлагает Django Haystack. Как видим, edge_ngram имеет стандартный анализатор. Но нам нужно, чтобы поиск находил, только точные совпадения и отсекал лишнее. Чтобы решить эту задачу, мы должны в маппинге явно указать, index_analyzer и search_analyzer. Это можно сделать явно, запросом к ES:
Теперь можно убедиться, что все работает правильно и в результатах нет мусора.
К сожалению, при перестроении индекса, все опять сломается. Чтобы этого не произошло придется написать свою версию ElasticsearchSearchBackend, указав свои настройки для edge_ngram в FIELD_MAPPINGS.