Feb 23 2014
Поиск при помощи Sphinx и PHP
Настройку Sphinx можно разбить на 3 этапа:
1. Установка Sphinx и конфигурирование.
2. Создание индекса базы и тестовый поиск из консоли.
3. Поиск из PHP.
Установка Sphinx не сложная.
Для windows: идём на официальный сайт и скачиваем дистрибутив.
Для Ubuntu достаточно воспользоваться командой
apt-get install sphinxsearch
После того как Sphinx установлен, можно приступать к конфигурированию. Так как Sphinx может обрабатывать запросы от нескольких проектов, логично было бы создать конфиг в домашней директории проекта (но так, что бы не было доступно из Интернет). Пример конфигурационного файла приведён ниже:
source content { # Тип данных # Доступные типы: mysql, pgsql, mssql, xmlpipe, xmlpipe2, odbc type = mysql # Необходимые параметры для подключения к базе данных sql_host = localhost sql_user = dbuser sql_pass = dbpass sql_db = dbname sql_port = 3306 # опциональный, по умолчанию 3306 # пред-запрос, выполняется перед выполнением основного запроса на получение данных из базы # В нашей базе данные хранятся в UTF-8, чтобы поиск по русским символам работал успешно выполним соответсвующий запрос sql_query_pre = SET NAMES utf8 # запрос, который получает данные документов для поиска # первым полем обязательно должен идти уникальный положительный ID документа sql_query = \ SELECT id, guid, title, h1, content \ FROM blogposts # поля, по которым может идти группировка, фильтрация и сортировка sql_attr_uint = guid # document info query, ONLY for CLI search (ie. testing and debugging) # optional, default is empty # must contain $id macro and must fetch the document by that id sql_query_info = SELECT * FROM blogposts WHERE id=$id } # индекс по контенту index content { # Источник данных для индексирования source = content # Адрес, где будут хранится данные индекса path = /home/demo/sphinx/index/blogposts # Индекс с учетом морфологии morphology = stem_enru # Минимальная длина слова для индексации min_word_len = 2 # Кодировка charset_type = utf-8 charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451 blend_chars = &, ., +, U+23 min_infix_len = 2 enable_star = 1 index_exact_words = 1 html_strip = 1 } indexer { mem_limit = 64M } searchd { listen = 9312 log = /home/demo/sphinx/log/searchd.log query_log = /home/demo/sphinx/log/query.log read_timeout = 5 max_children = 30 pid_file = /home/demo/sphinx/log/searchd.pid max_matches = 1000 seamless_rotate = 1 preopen_indexes = 1 unlink_old = 1 workers = threads # for RT to work binlog_path = /home/demo/sphinx/log }
Для создания индекса базы используется команда
indexer --config путь_до_файла_конфигурации
Если демон уже запущен, необходимо использовать опцию –rotate, в противном случае возможна ошибка при попытке пересоздания поискового индекса.
После того как индекс создан, можно произвести тестовый поиск:
search --config путь_до_файла_конфигурации поисковый_запрос
После того, как убедились, что поиск работает и сервер вернул результат, можно запустить поискового демона, который будет отвечать на запросы сделанные из PHP:
searchd --config путь_до_файла_конфигурации
Теперь приступим к тому, ради чего было проделано всё выше описанное: использование Sphinx API в PHP.
Скачиваем Sphinx API.
Для поиска воспользуемся следующим кодом:
$sphinx = new SphinxClient; $sphinx->SetServer($host, $port); $sphinx->open(); $sphinx->SetSortMode(SPH_SORT_RELEVANCE); $sphinx->setFieldWeights(array( 'title' => 10, 'h1' => 5, 'content' => 1, )); $sphinx->setLimits(0, 1000, 1000); $results = $sphinx->query($sphinx->escapeString($phrase), $index);
В переменной $results будут находиться результаты поиска.
При выводе можно генерировать сниппет с подсвеченными вхождениями искомой фразы:
$res = $sphinx->buildExcerpts($var, 'content', $phrase, array( 'before_match' => '<strong>', 'after_match' => '</strong>' ));
В $res будет содержаться сниппет.
Вот и всё, что хотелось рассказать. Дальше остаётся только экспериментировать с конфигурацией Sphinx. Более подробно о возможностях Sphinx можно почитать на официальном сайте.
blogposts