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
