Как стать автором
Обновить

Поиск — это просто

Время на прочтение3 мин
Количество просмотров3.6K
Google, конечно, ищет хорошо, но корпоративные ресурсы вывешивать на открытый доступ нельзя, покупать google-mini с его ограничениями тоже не вариант. А поиск по базе внушительных размеров(4 гигабайта текстов, по которым и необходим поиск) надо. А если добаить к поиску по тексту еще и поиск по каким-то параметрам, то тут и google-mini не поможет и совсем страшно становится.

Но не стоит паниковать! На помощь нам приходит Sphinx — поисковый движок с открытым исходным кодом, который можно прикрутить практически к чему угодно не прилагая особых усилий


Вся прелесть Сфинкса в том, что индексирует он не сайт целиком, рекурсивно бегая по ссылкам, вытаскивая информацию(иногда совершенно ненужную), а базу в удобном нам формате.

Сфинкс состоит из 3 частей: индексатор, утилита search для поиска из командной строки, демон searchd, к которому мы будем обращаться с поисковыми запросами. Так же в дистрибутиве есть набор примеров использования Сфинкса на разных языках.

Для начала, наверное, стоит поставить Сфинкс.
  1. Качаем исходники отсюда
  2. Распаковываем ( tar xzf sphinx-0.9.8.tar.gz )
  3. Конфигурируем ( ./configure --prefix=/path/to/sphinx)
  4. Собираем и ставим ( make install )

Теперь немного о настройке и работе

Разбираться с поисковиком будем на простом и понятном примере — возможной упрощенной структуре Хабрахабра =)

Пусть топик имеет такую структуру:
 Field    Type
-----------------------
 id       int(11)
 blog_id  int(11)
 Subject  varchar(255)
 Content  longtext

Ну и добавим к топику тэги, куда же без них — Веб 2.0 как-никак
 Field     Type
-------------------
 topic_id  int(11)
 tag_id    int(11)


Самая сложная задача поиска, которую нам предстоит решить и с которой Cфинкс успешно справится — это поиск по текстам топика с какими-то тегами в определённом блоге

Теперь, собственно, сконфигурируем Сфинкс на нашу базу.
Открываем конфиг ( PREFIX/etc/sphinx.conf ). Сконфигурировать нам придется 2 части:
  1. Источники
  2. Параметры индексации

Источник, как можно догадаться по названию — это место откуда Сфинкс берет данные для индексации. Источники могут быть двух типов: какая-нибудь СУБД(если не ошибаюсь, сейчас поддерживаются только mysql и postgres) либо база XML. Мы работаем с mysql-ем.

Задаем источник
source main
{
        type            = mysql
        sql_host        = localhost
        sql_user        = root
        sql_pass        =
        sql_db          = test
        sql_port        = 3306
        
        # до этого момента, думаю, все понятно

        # теперь нужно задать Сфинксу SQl-запрос, с помощью которого
        # он будет вытаскивать информацию из нашей базы

        sql_query       = \
                SELECT id, subject, content FROM Topics;

        # и запрос, по которому можно получить топик.
        sql_query_info  = SELECT * FROM Topics WHERE id=$id
}


Источник есть, теперь создадим индекс. Индексов может быть много, но нам пока что нужен только один.
index main
{
        source                  = main # используем источник main
        path                    = /var/lib/sphinx/main # место, где будет храниться индекс
        docinfo                 = extern # Это нам понадобится потом
        morphology              = stem_ru # Определяем морфологию, чтобы на запрос "хабрахабр"
                                          # нам выдалось еще и "хабрахабра", "хабрахабре"
        min_word_len            = 1 # минимальный размер слова. Вдруг захотим искать предлоги?
        charset_type            = utf-8 # это понятно - кодировка
        html_strip              = 0 # вырезать ли HTML.
                                    # В документации написано, что правильно работает только на
                                    # идеальном html'e, но честно говоря, никогда не пробовал
}

Параметры индексатора и поискового демона можно оставить по умолчанию.

Запускаем индексатор
bin/indexer --all

Опция --all означает, то переиндексировать нужно все индексы.

Индекс построен, можно попробовать поискать. Воспользуемся утилитой search.
bin/search хабрахабр

И получим список всех документов, где упоминается хабрахабр.

Поисковик готов! Теперь решим задачу, про которую говорилось ранее: поиск по топикам с определёнными тэгами в конкретном блоге.

Для этого Сфинксу нужно знать какие тэги к каким топикам относятся и в каком блоге какой топик находится.

К каждой записи можно добавить любое количество атрибутов. У нас их два: топик и блог. Говорим Сфинксу об этом. В конфиге источника добавляем строчки:
        # tags
        sql_attr_multi = \
                        uint tag from query; \
                        SELECT topic_id, tag_id from tags;
        # blogs
        sql_attr_multi = \
                        uint blog from query; \
                        SELECT id, Blog from Topics;

После этого переиндексируем базу и через утилиту search проверяем результат:
bin/search -f tag 42 поисковые слова

Сфинкс выдаст нам список топиков, помеченных тэгом с номером 42 и содержащих «поисковые слова».
К сожалению, утилита search не умеет ограничивать поиск по нескольким атрибутам, но через API это возможно(Если будет какой-нибудь резонанс, то отдельно опишу API).

Хочется добавить, что у Сфинкса довольно мощный «язык» запросов к нему. В расширенном решиме можно указывать какие столбцы с чем матчить, использовать выражения со скобками, сортировать и группировать результаты поиска, задавать функцию сортировки самостоятельно и еще много чего.

Полная документация на английском лежит здесь.

Ну вот и все.

P.S. Первый топик. Дебют удался? =)
Теги:
Хабы:
+87
Комментарии124

Публикации

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн