Какой опыт работы с поисковыми системами Elasticsearch, Sphinx, Manticore
Что проверяют
Понимаете ли вы, как устроен полнотекстовый поиск, и можете ли обосновать выбор движка, а не «поставили Elasticsearch, потому что все ставят». Уточняют обычно про синхронизацию индекса с основной базой и про настройку релевантности.
Как отвечать
Назовите опорные понятия и привяжите их к своему проекту на Python:
- обратный индекс: слово указывает на список документов, где оно встречается. На этом держатся все три движка;
- анализ текста: токенизация, нижний регистр, стемминг или морфология для русского, стоп-слова. В Elasticsearch это
analyzerв маппинге поля, в Sphinx и Manticore настройки индекса вродеmorphologyиmin_word_len; - ранжирование: в Elasticsearch по умолчанию BM25, в Sphinx и Manticore набор ранкеров, которые учитывают BM25 и близость слов в документе;
- Sphinx и Manticore: Manticore это ответвление Sphinx, которое активно развивается и добавило HTTP JSON API и репликацию. Оба понимают SQL-подобный SphinxQL по протоколу MySQL, поэтому из Python к ним ходят обычным MySQL-драйвером;
- Elasticsearch: данные разложены по шардам и репликам, REST API, агрегации для фасетов. Из Python это официальный клиент
elasticsearchили OpenSearch сopensearch-py; - синхронизация: источник правды остаётся в PostgreSQL или MySQL, а индекс догоняет его полной переиндексацией, дельтой по
updated_at, очередью событий или CDC. Загрузка пачками черезhelpers.bulk, смена маппинга через новый индекс и переключение алиаса без простоя.
Дальше ваш случай: объём данных, какие запросы, что настраивали и чем мерили результат. Если работали только с одним движком, так и скажите, а остальные сравните по документации, не приписывая себе опыт.
Где спотыкаются
Используют Elasticsearch как основную базу. Транзакций у него нет, а новый документ попадает в поиск не сразу, по умолчанию после refresh раз в секунду.
Не могут объяснить, почему запрос «кошки» не находит «кошка». Ответ: не настроена морфология или стемминг.
Пытаются поменять тип поля в живом индексе. Маппинг существующего поля не меняется, нужен новый индекс и _reindex.