Стандартный полнотекстовый поиск MySQL не решает многих задач и не настолько производителен, как поиск Sphinx. Привожу простой пример установки и настройки Sphinx в debian для организации поиска на сайтах. Установим версию 2.2.11 из стандартного репозитория: apt install sphinxsearch
Далее заходим /etc/sphinxsearch/sphinx.conf и настраиваем конфиг подобным образом:
# # Minimal Sphinx configuration sample (clean, simple, functional) # source src_test_db { type = mysql sql_host = localhost sql_user = root sql_pass = sql_db = test_db sql_port = 3306 # optional, default is 3306 sql_query = \ SELECT id, category_id, UNIX_TIMESTAMP(date_created) AS date_created, text \ FROM questions sql_attr_uint = category_id sql_attr_timestamp = date_created sql_field_string = text sql_query_pre = SET CHARACTER_SET_RESULTS=utf8 sql_query_pre = SET NAMES utf8 } index index_test_db { source = src_test_db path = /var/lib/sphinxsearch/data/index_test_db morphology = stem_enru html_strip = 1 min_word_len = 2 min_infix_len = 1 index_exact_words = 1 expand_keywords = 1 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+0435, U+451->U+0435, U+2A, U+2D, U+00AB, U+00D7 } indexer { mem_limit = 256M } searchd { listen = 127.0.0.1:9806:mysql41 log = /var/lib/sphinxsearch/log/searchd.log query_log = /var/lib/sphinxsearch/log/query.log read_timeout = 5 max_children = 30 pid_file = /var/run/sphinxsearch/searchd.pid seamless_rotate = 1 preopen_indexes = 1 unlink_old = 1 workers = threads # for RT to work binlog_path = /var/lib/sphinxsearch/data }
Для первичного запуска хватит, потом желательно добавить стоп слова и прочие настройки на основе лога запросов и их скорости. В общем в этот файл придется заглянуть ещё раз 100500(простая настройка и запуск Sphinx да) Перезапустим службу и проиндексируем все добавленные конфиги:
systemctl restart sphinxsearch indexer --all --verbose
Индексация/переиндексация БД таблицы объемом 5 млн записей в 2.7 гига занимает чуть больше 2 минут. Скорость отменная. Чтобы поиск заработал необходимо запустить демон с соответствующим конфигом:
/usr/bin/searchd -c /etc/sphinxsearch/sphinx.conf
Теперь мы можем искать по индексу из консоли или из под php. Для поиска из консоли mysql -h0 -P9806 и собственно запрос:
SELECT *, SNIPPET(text, 'test search query') as `snippet`, WEIGHT() AS `w` FROM `index_test_db` WHERE MATCH('test search query') LIMIT 1000
Из под php соединяемся так: $db_index = new mysqli(‘localhost:9806’); бд выбирать не нужно, сразу можно делать запросы, как в обычной базе. Только запросы делаются не к таблице, а к её индексу. Сервис слушает порт 9806 на локальной lo петле и протоколу SphinxQL. В примерах по данному протоколу обычно указывается порт 9306, но у меня он занят. Также в образцах конфигов данный порт зачем-то открыт для всех желающих извне… Хм… это 100% точно есть хорошо. Например, если в конфиге настроено обновление индексов в реальном времени, то это получается, можно с сервера дяди Васи «обновить» чего-нибудь кому-нибудь тому, кто не вдумчиво скопипастил конфиг? А таких товарищей 99%, прям бери в гугл бей «9306:mysql41», находи где они постят свои проблемы со sphinx на форумах, определяй их серваки и в путь. Поэтому в конфиге обязательно 127.0.0.1:9806:mysql41 Слушает только локалка!
Для переиндексации необходимо выполнить:
indexer -c /etc/sphinxsearch/sphinx.conf --rotate <source_name> indexer -c /etc/sphinxsearch/sphinx.conf --rotate --all # После переиндексации killall searchd и снова запуск демона. killall searchd /usr/bin/searchd -c /etc/sphinxsearch/sphinx.conf
Можно поставить данные задачи на крон, обновляя индексацию всех ресурсов и перезапуская демон. Одной командой:
indexer -c /etc/sphinxsearch/sphinx.conf --rotate --all && killall searchd && sleep 1 && /usr/bin/searchd -c /etc/sphinxsearch/sphinx.conf
Но лучше сделать по другому. Демон нужно запускать при каждом перезапуске системы, поэтому создадим соответствующий unit файл, который будет это делать. И теперь наша крон задача на переиндексацию будет выглядеть так:
indexer -c /etc/sphinxsearch/sphinx.conf --rotate --all > /dev/null && systemctl restart runsearchd > /dev/null
Здравствуйте!
1. Как осуществляется сортировка на уровне запроса к Spinhx.
2. Почему максимум 1000 резултатов?
3. Кажись что не всё индексируется, то есть — некоторые запросы не вазращают результат.
Не помешала бы инструкция по Manticore — это что то вроде нового Spinhxsa.
Здравствуйте! 1. Для каждого запроса расчитывается WEIGHT() это вес, релевантность. По ней и сортировка автоматически, как она там осуществляется это уже сам движок копать надо. 2. В старых версиях в конфиге был параметр max_matches, теперь это можно задавать в самом запросе через OPTION
select * from index_tab where match(‘1’) limit 7898 OPTION max_matches=5000;
Параметр влияет насколько я понимаю на производительность, чем он меньше, тем быстрее. 3. Зависит от настроек конфига, там масса параметров в директивах индексации.
Manticore весьма интересный проект судя по всему, спасибо, буду иметь его ввиду на будущее.
Не уверин что ограничение 1000 не баг данной версии… Так-же не плохо этокое руководство по обновлению 2.11 на более новые версии Shinks, которые вроде как есть. Спасибо!
А что там руководить по обновлению, вот сейчас Sphinx 3.4.1 самый новый, он вообще установки, сборки не требует, скачал и в локальном каталоге любом развернуть можно. Каталоги под индексы и все данные какие угодно можно ставить. Конечно старые индексы наверное лучше не юзать, новые в другом каталоге создать. Демон старый останавливаем потом, новый с новым конфигом запускаем и вперед. Или если запуск searchd демона в автозагрузке служба прописана, как у меня на примере тут есть, тогда там меняем путь на новый конфиг файл и новый searchd демон. Там вся работа по обновлению вообще сводится тупо к работе с каталогами, что куда, да и всё. У меня единственно в директивах индексации параметр sql_attr_timestamp(удаленв новых версиях) на sql_attr_uint заменить пришлось и всё. Да и ротацию логов в наверное нужно ещё прописать в /etc/logrotate.d/sphinxsearch, вот не помню что там с ними, я это прописывал или установщик ранее, ну например:
/var/log/sphinxsearch/*.log {
daily
rotate 4
compress
missingok
sharedscripts
postrotate
start-stop-daemon -K -p /var/run/sphinxsearch/searchd.pid -s USR1 -x /usr/bin/searchd -q
endscript
}
И для индексации из mysql нужны драйвера
apt-get install libmysqlclient-dev libpq-dev unixodbc-dev
apt-get install libmariadb-client-lgpl-dev-compat
Так оно для Вас дело-то пластиковое… Для меня это очень мутно. Вы поймите, что ‘чайникам’ хорошо — когда есть пошаговые инструкции. Тогда каждый чайник может себя(хоть на миг) почувствовать профессионалом… Я думаю, что нюансов то там куча… к примеру я понятии не имею как это «скачал и в локальном каталоге любом развернуть» Я понимаю что это не запуск шаттла, но полагаю, что Ваш сайт юзают и чайники… 🤣👍 так им то и хорошо — коды всё по полочкам. К примеру — вот нафига мне новая версия Sphinx? Да потому что на этой sphinxApi не работает на php7. 😉😆 Ну то есть — я немогу сделать высвечивания, livesearch…
Спасибо!
Для подсветки есть встроенная функция SNIPPET() которая и на 2.x версиях есть. Api зная php можно написать своё, используя обычные SQL запросы в нем к индексам.
Выложил тут готовое решение https://itnots.ru/linux/sphinx-3-4-1-nastrojka-servisa-odnoj-komandoj-s-avtozagruzkoj-rotacziej-logov-i-php-api/
Спасибо Вам. Скажите своё мнение — как по функционалу и быстродействию Вы оцениваете работу 3 и 2 версии Sphinx? То есть — есть лил смысл переписывать APi для 2версии?
Я особо разницы не вижу, в бд по 10-20 млн. записей, ищет и тот и этот быстро. Был затык из-за всевозможных предлогов и междометий, долго длился поиск, это нагружало сервак, причем директивы конфигруции не помогали по таймауту и т.п. и в запросе опцию прописывал, есть такая максимальное время запроса. Только стоп лист помог. Даже скрипт написал для его автообновления https://github.com/avtobys/sphinx-stopwords-updater чтобы треш исключить этот. Анализирует логи за несколько дней, собирает самые длительные запросы и вычленяет слова которые привели к их тормозам. Возможно в 3 это пофиксили, не знаю, не экспериментировал.
Еще вопросик, есть ли в2 или 3. версие наработки по livesearch чтобы применить его с ‘коробки’? Иле это нужно полностью достраивать?
Спасибо!
Нет, это уже javascript, если фронтенд имеете ввиду. Тут кому что нужно уже, индивидуально. А если php, ну вот например https://github.com/avtobys/sphinx-3.4.1/blob/master/api/test.php кидаете запросы и получаете json ответы. Единственное, рекомендовал бы не кидать запрос сразу по событию ввода, а делать 300-400 мс таймаут, ожидая нажатия следующей клавиши, и либо отменять предыдущий таймаут, либо отправлять запрос. Визуально это будет не заметно, поиск как был «на лету», так и будет, но поможет избежать лишних запросов, когда либо быстро набирают текст, либо, что ещё хуже зажимают backspace — на каждый стертый символ идет событие и получается куча ненужных запросов.
Вроде понятно — буду пробовать реализовать на 2версие. А там кто знает… :) Конечно это была бы хорошей новой темой для Вас типа ‘ реализация live search на Sphinx’ Спасибо!