Puma @opium read-only
Пользователь
16 июля 2012 в 18:16

Разработка → Улучшаем релевантность поиска в sphinxsearch из песочницы

Sphinxsearch является поисковым движком для быстрого fulltextsearch, может получать данные из mysql, oracle и mssql, может выступать сам хранилищем(realtime индексы). Также sphinx имеет режим работы через api и через sphinxql — аналог протокола sql(с некоторыми ограничениями), что позволяет подключить поиск через sphinx на сайте с минимальным изменением кода. Это один из немногих великих, крупных и открытых проектов разработанный в России. На моей жизни я видел как sphinx обрабатывает порядка 100-200 поисковых запросов на 2 миллиона записей из mysql и при этом сервер свободно дышал и его не тошнило, mysql начинает умирать уже на 10 запросах в секунду на аналогичном конфиге.

Основная проблема документации sphinx на мой взгляд малое количество примеров для большинства интересных настроек, сегодня постараюсь рассказать в примерах о них. Опции которые я затрону касаются в основном алгоритмов и вариаций поиска. Все кто плотно работает со sphinx не узнают ничего нового, а новички надеюсь смогут улучшить качество поиска на своих сайтах.

Sphinx содержит две независимые программы indexer и searchd. Первый строит индексы по данным взятым из базы данных, второй производит поиск по построенном индексу. А теперь перейдем к настройкам поиска в sphinx.

morphology

Позволяет задать морфологию слов, я использую только стемминг. Алгоритм стемминга с помощью набора правил для языка обрезает окончания и суффиксы. Стемминг не использует готовые базы слов, а основан на определенных правилах обрезания для языка, что делает его маленьким и быстрым, но это же и добавляет ему минусы так как он может совершать ошибки.

Пример нормализации слова стеммингом на русском.
Слова “яблоко”, “яблока”, “яблоку” будут обрезаны в “яблок” и любой поисковый запрос с вариацией слова “яблока” будет тоже нормализован и найдет записи со словами которые были описаны выше.

Для английского слова “dogs” и “dog” будут нормализованы к “dog”.
К примеру в sphinx должен положить в индекс слово кучерявый, в индекс попадет слово кучеряв и будут находиться вариации кучеряво, кучерявая и др.
Включить стемминг можно для русского, английского или обоих языков

morphology = stem_en
morphology = stem_ru
morphology = stem_enru

Также можно использовать опции Soundex и Metaphone они позволяют использовать для английского языка с учетом звучания слов. Не использую в работе данные алгоритмы морфологии так что если кто то знает много про них буду рад почитать. Для русского языка такие алгоритмы позволяли бы получать из слов “солнце” и “сонце” нормализованную форму “солнце”, которая получается на основании звучания и произношения этих слов.

morphology = stem_enru, Soundex, Metaphone

Можно подключать и внешние движки для морфологии или написать свой.

Wordforms


Позволяет подключать свои словари словоформ, хорошо применяется на специализированных тематических сайтах, имеет хороший пример в документации.

core 2 duo > c2d
e6600 > c2d
core 2duo > c2d

Позволит найти статью о core 2 duo для любого поискового запроса от модели до вариаций названия.

конопля > травка
дурь > травка
моя прелесть > травка
трава свободы > травка
че покурить > травка
есть чё > травка

А данный словарь позволит вашим пользователя легко найти информацию о травке на сайте.

Для словоформ используются файлы в формате ispell или MySpell(которые можно сделать в Open Office)

wordforms = /usr/local/sphinx/data/wordforms.txt

enable_star


Позволяет использовать звездочки в запросах, к примеру по запросу *пр* будут найдены проспект, привет, апроксимация и др.

enable_star = 1

expand_keywords


Автоматически расширяет поисковый запрос до трех запросов

running -> ( running | *running* | =running )

Просто слово с морфологией, слово со звездочками и полное совпадения слова. Раньше этой опции не было и чтобы поискать со звездочками мне приходилось вручную делать дополнительный запрос, сейчас все включается одной опцией. Так же автоматом полное совпадение будет в поисковой выдаче выше чем поиск со звездочками и морфологией.

expand_keywords = 1

index_exact_words


Позволяет на ряду с морфологически нормализованной формой хранить и оригинальное слово в индексе. Это сильно увеличивает размер индекса, но с учетом предыдущей опции позволяет выдавать результаты более релевантно.

К примеру есть три слова “дыня”, “дыне”, “дыню” без этой опции все три слова будут сохранены в индексе как дын и на запрос “дыне” будут выданы в порядке добавления в индекс то есть “дыня”, “дыне”, “дыню”.
Если же включить опции expand_keywords и index_exact_words то на запрос “дыне” будет более релевантная выдача “дыне”, “дыня”, “дыню”.

index_exact_words = 1

min_infix_len


Позволяет индексировать части слова инфиксы, и искать по ним с применением *, вроде search*, *search и *search*.
К примеру при min_infix_len = 2 и попаданию в индекс слова “тест”, будут сохранены в индекс “те”, “ес”, “ст”, “тес”, “ест”, “тест” и по запросу “ес” будет найдено это слово.

Обычно я использую

min_infix_len = 3

Меньшее значение генерит слишком много мусора и помните что использование этой опции сильно увеличивает индекс.

min_prefix_len


Является дочерним для min_infix_len и делает почти тоже самое только сохраняет начало слов или префиксы.
К примеру при min_infix_len = 2 и попаданию в индекс слова “тест”, будут сохранены в индекс “те”, “тес”, “тест” и по запросу “ес” будет найдено это слово.
min_prefix_len = 3

min_word_len



Минимальный размер слова для индексации, по умолчанию 1 и индексирует все слова.
Обычно использую
min_word_len = 3
Слова меньшего размера обычно не несут смысловой нагрузки.

html_strip


Вырезает все html теги и html комментарии. Эта опция актуально если вы строите свой google/yandex на базе sphinxsearch. Запустили спайдера спарсили сайт, загнали его в базу данных, натравили indexer и эта опция позволит избавиться от хлама в виде html тегов и искать только по контенту сайта.

Сам к сожалению не использовал, но в документации написано что может косячить со всякими xml и не стандартным html(к примеру где попало открывающимся и закрывающимся тегам и пр).

html_strip = 1

Буду рад любым вопросам и уточнениям.
Офсайт sphinxsearch.com.
Если статья была вам интересна не поленитесь плюсануть.
Puma @opium
карма
1,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (17)

  • +7
    Спасибо за статью, думаю начинающим разбиратся со сфинксом будет полезно.
    Хотелось бы кое что добавить:
    1. Морфология
    Минусом морфологии сфинкса является стемминг (не все слова изменяются префиксами/суффиксами), а также его наличие всего для нескольких языков (русского, английского), что значительно сужает круг его применения.
    Для себя решали задачу все-таки через полноценные словари словоформ (для php хорошо зарекоендовал себя phpMorphy, на питоне, соответвенно pyMorphy).
    2. Словоформы
    тоже достаточно спорная реализация — при построении индекса все слова из словоформы заменяются на один и тот же CRC32, соответственно после изменения в словоформах необходимо полностью перестроить индекс (у нас он достигает 300Гб).
    Для себя решали отдельным справочником словоформ, которые заменяли слово непосредственно в запросе
    • 0
      Спасибо, и то и другое я кажется смогу применить. У вас на редкость ценный комментарий.
    • 0
      индексация словоформ по идее должна решатся включением index_exact_words
      • 0
        Как это решает проблему перестройки индекса? И причем тут словоформы и index_exact_words?
        Мне кажется я не до конца понимаю ваш комментарий.
    • 0
      А как вы phpMorphy используете? Храните в отдельной таблице текст пропущенный через него или как-то по другому?
      • 0
        При индексации токенизируем текст и слова приводим к начальной форме (формам, если их несколько). Тоже самое при поиске — токенизируем строку запроса, слова приводим к начальной форме и передаем сфинксу.
        При таком подходе решается проблема поиска по словоформам.

        Единственный нюанс такого подхода — phpMorphy нужно указать хранить словари в разделяемой памяти, тк при чтении с диска на большой нагрузке упираемся в чтение, а при хранении в памяти скрипта уписаемся в потребление памяти.
        Правда phpMorphy хранит может хранить словари только в одном сегменте памяти, так что если их много, то нужно будет дорабатывать его чтобы он умел работать с несколькими сегментами.
  • +2
    Вы поаккуратнее про ТРАВКУ! По новому закону, так и Хабр закрыть могут =)
  • +2
    Основная проблема документации sphinx на мой взгляд малое количество примеров для большинства интересных настроек, сегодня постараюсь рассказать в примерах о них.

    Зато это позволяет срубить денег на тех.поддержке и консультациях. :) Такая вот система монетизации.
    Лично мне было сложно недавно прикручивать поиск с опечатками по статье Аксёнова к node.js + mongoDB. Прикрутил наполовину, как смог, но всё равно рад.
    Так что мне истории успеха с применениех сфинкса безумно интересны.

    • 0
      Проект то для нас халявный и сообщество теоретически должно делится. В том же php в комментах море примеров по многим функциям. Вы вот с горем пополам решили проблему, а с остальными поделились решением?
      • 0
        Ссылки приложены, вы о чем?
        • 0
          Нет, у вас статья хорошая я ответил на комментарий выше.
          • 0
            Так он тоже дал ссылку на статью как сделать.
  • 0
    >sphinxql — аналог протокола sql
    sql — это язык, а не протокол
    • 0
      Возможно там стоило написать аналог протокола mysql, не очень много работал в этом режиме.
  • 0
    Можно написать еще про Real Time index, сейчас столкнулся, забавная штука для мгновенной индексации изменений.
    • 0
      Большинство статей про реалтайм индексы в рунете наполнены откровенным непониманием как их использовать, прочитал 10 штук и мне показалось, что реалтайм индексы самая ненужная вещь в сфинксе. Эти статьи писали люди, которые не применяют эти индексы и дают примеры, которые просто оторваны от жизни и вводят читателей в заблуждение.
      Если хватит сил напишу статьи про дельта и реалтайм индексы и как их правильно готовить.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.