Feb
15
|
Sphinx. Что это такое и с чем его едят.
|
Итак, сфинкс.
Постараюсь немного рассказать о нем с наглядными примерами и настройкой.
Sphinx (SQL Phrase Index) — полнотекстовый поисковой движок, опубликованный под лицензией GPLv2, что дает возможность его бесплатного использования в своих проектах.
Сразу же возникает вопрос — «чем же Sphinx отличается от других поисковых движков и почему именно его стоит использовать?»
Кроме всех достоинств Sphinx (быстрая индексация, поддержка MySQL и PostgreSQL, морфология и т.д.) я бы отметил еще такие особенности, как распределенный поиск (возможность размазывать поисковой движок на несколько машин) и довольно широкое использование движка в hiload проектах (к примеру на Habrahabr и т.д.).
Я много слышал о Sphinx, но до этого не было повода и надобности в его использовании. Однако времена меняются.
Я уже рассказывал про создание видеохостинга своими руками . В один прекрасный день встал вопрос поиска по базе видеофайлов. До этого использовался гуглопоиск, но его качество оставляло желать лучшего в плане поиска по видео, несмотря на то, что Sitemap для video.google.com был скормлен.
Поэтому я задался вопросом создания поиска по видео. Естественно, изобретать велосипед мне не хотелось (писать поиск с нуля), поэтому начал смотреть на готовые решения и вспомнил про Sphinx. Почему бы и нет? Познакомиться с новой для себя технологией, заодно решить задачу.
Сказано — сделано. Начал изучать документацию. Сначала вообще мало что было понятно.
Установка
Начал отсюда —
yum list | grep sphinx
yum install sphinx.x86_64
Конфиг
Дальше отредактировал конфиг, предварительно скопировав его с директории установки и переименовав в sphinx.conf (тут довольно много времени пришлось убить на ознакомление с документацией и правильной настройки конфига. В итоге получилось такое:
# Minimal Sphinx configuration sample (clean, simple, functional)
#source video
{
type = mysqlsql_host = localhost
sql_user = myuser
sql_pass = mypass
sql_db = mydb
sql_port = 3306 # optional, default is 3306 sql_query_pre = SET NAMES utf8 sql_query_pre = SET SESSION query_cache_type=OFFsql_query = \
SELECT `desc`, `longdesc`, \
(SELECT count(`id`) FROM `comments` WHERE `item_id` = v.`video_id`) as comments, \
UNIX_TIMESTAMP(`date`) AS date_added, `views` as views \
FROM video v WHERE `decoded` = ’1’ AND `deleted` = 0
sql_attr_uint = comments
sql_attr_uint = views
sql_attr_timestamp = date_added
}index video
{
source = video
path = /var/lib/sphinx/video
docinfo = extern
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
enable_star = 1 min_prefix_len = 5 html_strip = 1 prefix_fields = desc, longdesc
morphology = none
}indexer
{
mem_limit = 32M
}searchd
{
port = 3312 log = /var/log/sphinx/searchd.log
query_log = /var/log/sphinx/query.log
read_timeout = 5 max_children = 30 pid_file = /var/run/sphinx/searchd.pid
max_matches = 1000 seamless_rotate> = 1 preopen_indexes = 0 unlink_old = 1 }
В принципе все довольно стандартно, главное было подобрать параметры «под себя». Про все параметры можно прочесть в документации, поэтому по ним пробегусь довольно коротко:
sql_query_pre = SET NAMES utf8 sql_query_pre = SET SESSION query_cache_type=OFF
Эта часть означает, что мы делаем два предварительных запроса к базе до выполнения основного запроса на выборку данных, в которых выставляет кодировку utf8 для считываемых данных и отключаем кеширование запросов.
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
Для правильного поиска по индексу выставляем индексатору правильную кодировку данных и список допустимых символов в этой кодировке (куда, кстати, попадают и русские буквы)
enable_star = 1 min_prefix_len = 5 html_strip = 1 prefix_fields = desc, longdesc
Включаем префиксирование до 5 символов для полей desc, longdesc и вырезаем все
Проверка работоспособности и сron
Т.к. конфиг создан, самое время проверить, что он правильно работает и в нем нет ошибок. Для этого в консоли набираем вот такое:
indexer video
–rotate
Результат будет подобен этому, если с конфигом все хорошо:
Sphinx
0.9.8.1-release (r1533)
Copyright © 2001–2008, Andrew Aksyonoffusing config file ’/etc/sphinx/sphinx.conf’…
indexing index ’video’…
collected 4549 docs, 0.3 MB
sorted 0.1 Mhits, 100.0% done
total 4549 docs, 308441 bytes
total 0.401 sec, 768480.12 bytes/sec, 11333.82 docs/sec
rotating indices: succesfully sent SIGHUP to searchd (pid=31147).
Параметр
Если ошибок нету и индекс создался — самое время запустить демон, если еще не запущен (/etc/init.d/searchd start) и занести индексацию данных в крон (я поставил обновление индекса раз в 30 минут):
30 * * * * /usr/bin/indexer
–rotate video > /dev/null 2>&1
Остается проверить, что поиск работает правильно. Для этого в консоли опять же следует набрать
search lol
и получим такой результат:
Sphinx
0.9.8.1-release (r1533)
Copyright © 2001–2008, Andrew Aksyonoffusing config file ’/etc/sphinx/sphinx.conf’…
index ’video’: query ’lol ’: returned 2 matches of 2 total in 0.000 secdisplaying matches:
1. document=1501, weight=1, comments=0, rating=0, date_added=Thu Oct 22 12:57:55 2009, views=406 2. document=2502, weight=1, comments=2, rating=4, date_added=Mon Nov 30 11:18:40 2009, views=415 words:
1. ’lol’: 2 documents, 2 hits
Отлично — найдено два совпадения, значит поиск работает правильно.
Sphinx и PHP
Т.к. поиск работает — остается теперь запрашивать данные у демона из PHP и выводить результаты. Для этого есть два пути — использовать PHP API просто делая инклуд его в код или установить расширение из pecl
Я решил не тягать за собой код и поставить расширение — «взула и забула». Как обычно — yum install
Дальше все просто — читаем мануал отсюда — http://php.net/sphinx и пишем в нужном месте обращение к демону searchd:
$s = new SphinxClient;
$s->setMaxQueryTime(3);
$s->setSortMode(SPH_SORT_RELEVANCE);
$s->setMatchMode(SPH_MATCH_ANY);
$result = $s->query($query);
Код довольно тривиален и призван лишь показать пример элементарного использования. Естественно, сюда можно добавить лимитирование (setLimits) и другие вкусные вещи на ваше усмотрение — в этом вам поможет документация с указанного выше раздела.
Замечание: запрос к sphinx возвращает
Заключение
Данный обзор не претендует на полноту и носит лишь ознакомительный характер для демонстрации базовой установки и настройки sphinx для ваших надобностей.
Автор готов оказать помощь (в пределах своих знаний) в комментариях для тех, кто столкнулся с
Личное мнение автора — движок очень легкий, приятный в использовании и не требует долгих танцев с бубном над собой для приведения «в чувство».
P. S. Совсем недавно открылся сайт школы фриланса, к созданию сайта которой я приложил свою руку. Проект работает на базе маленькой CMS системки, которую я создал с помощью Zend Framework.
P. P. S. Написал анонс нового проекта школы фриланса — «стенка на стенку» на freelancehack.ru. Знаю, меня читают фрилансеры, возможно заинтересует.
15.02.2010 в 05:03
Sphinx 0.9.9 очень интересен тем, что умеет прикидываться SQL-сервером и для работы с ним не нужно никаких API и т.д.
Делается SQL-запрос посредством штатных средств РНР и вуаля… все работает без каких-либо дополнительных примочек
15.02.2010 в 10:32
А что-то из вашего пример не совсем ясно в чем преимущество Sphinx перед тем же встроенным в MySQL индексом FULLTEXT? Он работает очень быстро и имеет немало настроек. Один недостаток – таблицы должны быть типа MyISAM.
15.02.2010 в 10:35
MyISAM – уже из-за єтого его не стоит использовать
а так же FULLTEXT он не понимает русский – ни стимминга, ни морфологии
15.02.2010 в 11:31
hyzhak:
В целом вроде и до 0.9.9 есть такое понятие, как SphinxSE – делается запрос к MySQL, а он уже сам к searchd обращается.
Sphinx работает не только с MyISAM, но и с InnoDB, это раз.
Два – может быть вообще не MySQL, а PostgreSQL например или MSSQL или ODBC.
Ну и три – как уже сказано – это морфология, стиминг.
15.02.2010 в 12:10
SphinxSE vs SphinxQL
- SphinxSE может работать только c MySQL и то только версии 5.*
- нужно перекомпиливать MySQL сервер
- все же запросы не на нативном SQL (что-то типа WHERE query=’test sort=attr_asc:group_id’)
- SphinxQL какая база пофиг
- практически нативный SQL (есть ограничения, но думаю скоро доделают, что бы свести их к минимуму)
15.02.2010 в 17:10
Я FULLTEXT применял для англоязычных проектов, где нужно было оптимизировать поиск. Там таблицы уже были MyISAM, а морфология не так важна. Хотя про русский язык я что-то совсем не подумал (стыд и срам мне ).
19.04.2010 в 19:07
подскажите, как использовать Sphinx для поисках в нескольких базах данных?
20.04.2010 в 11:18
Vok:
Имеются ввиду совершенно разные базы? Или базы с одинаковой структурой?
15.06.2011 в 09:29
Всем привет! Подскажите, почему не работает следующая строка
$res = $cl->Query(“SELECT * FROM goods WHERE MATCH(‘@pp кирпич’)”);
Куда необходимо писать запросы?
27.07.2011 в 04:50
tazododu:
Как именно “не работает” ?
27.07.2011 в 14:41
я уже разобрался, просто не сразу понял, что в api нельзя писать запросы на sphinxql