me.neoascetic

Sphinx и опциональный пробел-разделитель слов с дефисом

Есть документы со словами, некоторые разделены дефисами (например, “Mazda CX-7”), и есть поисковой движок Сфинкс. Пользователь может искать по трём формам слов: оригинальной (“CX-7”), с пробелом вместо дефиса (“CX 7”), и без дефиса вообще (“CX7”). Задача: малой кровью, то есть минимально изменив текущее состояние системы и потратив на это как можно меньше времени, реализовать такую возможность.

Решением для меня оказалось использование настроек ignore_chars и regexp_filter (доступна с версии 2.1.1-beta):

ignore_chars = -
regexp_filter = \b([\w\d]+)-([\w\d]+)\b => \1 \2 \1\2

Благодаря regexp_filter, Сфинкс для каждого слова с дефисом положит в индекс, по факту, три слова: левую часть относительно дефиса (“CX”), правую часть (“7”), и склеенный вариант двух слов (“CX7”). Директива ignore_chars отвечает за то, чтобы дефис был удалён из запроса пользователя перед поиском, то есть оригинальный вариант будет сведён к третьему, а тот уже будет в индексе.

У этого подхода есть недостаток: не будет работать строгий поиск, т. е. запрос “Mazda CX7” (в кавычках) выдаст пустой результат из-за того, что в индексе после “Mazda” идёт “CX 7”. Конкретно в моем случае это не было проблемой - но если что, я предупредил.

Альтернативной этого подхода является использование триграмм: он, помимо того что не имеет описанного выше недостатка, также может помочь учитывать опечатки пользователя - но при этом сложнее в реализации и поддержке.