Задача: реализовать полнотекстовый поиск по сайту с помощью Sphinx.
1. Устанавливаем Sphinx
Устанавливаем через sudo apt-get install sphinxsearch
либо по инструкции из документации для вашей ОС.
Далее правим настройки поискового демона/etc/default/sphinxsearch
изменяем на START=yes
, для авто-запуска.
2. Настраиваем Sphinx и запускаем
Правим /etc/sphinxsearch/sphinx.conf
по своим нуждам. Настройку конфига не описываю, очень объемно. Из основного: описываем запрос на получения данных и указываем дополнительно атрибуты (зачем описано чуть ниже):
sql_query = \
SELECT id, type_id, title, content \
FROM table \
WHERE id >= $start AND id <= $end
sql_query_range = SELECT MIN(id),MAX(id) FROM file
sql_attr_uint = type_id
Когда конфиг отредактирован и сохранен запускаем индексацию и стартуем поисковый демон:
indexer --all
searchd
Дальнейшую переиндексацию можно проводить с помощью команды indexer --rotate --all
без перезапуска. Для периодической индексации новых материалов можно добавить задание в /etc/crontab:
*/30 * * * * /usr/bin/indexer --rotate --all > /dev/null 2>&1
В старых версиях проверить поиск можно было в консоли:
search -q поисковый запрос
, в новых выпилили.
Известные ошибки
sphinx returned 0 matches of 0 total
Если при проверке sphinx не возвращает результатов на русском, убедитесь что в конфиге имеется строка sql_query_pre = SET NAMES utf8
которая задает кодировку подключения.
SQLSTATE[HY000] [2054] Server sent charset unknown to the client. Please, report to the developers
Проверьте какая версия Sphinx у вас. Если у вас релиз ниже r3340, например Sphinx 2.0.4-id64-release (r3135). То обновите версию Sphinx до последней актуальной. Ошибка исправлена в релизе r3340.
3. Работа с Sphinx в Yii2
Устанавливаем расширение через Composer
composer require --prefer-dist yiisoft/yii2-sphinx
Добавляем в конфигурацию:
return [
//....
'components' => [
'sphinx' => [
'class' => 'yii\sphinx\Connection',
'dsn' => 'mysql:host=127.0.0.1;port=9306;',
'username' => '',
'password' => '',
],
],
];
В контроллере используем по аналогии с привычным компонентом Query:
use yii\sphinx\Query;
$query = new Query;
$rows = $query->from('index')
->match($_GET['поисковая строка'])
->all();
Где index
— поисковый индекс настроенный вами в конфигурации. Метод match()
по умолчанию экранирует все спецсимволы. На выходе будет сформирован SQL-подобный запрос, содержащий конструкцию MATCH
.
Резульатом мы получим массив с id, и другими атрибутами заданными в конфигурации sphinx, которые удовлетворяют нашему запросу.
Зачем нужно задавать атрибуты? По-умолчанию в сфинксе fulltext-поля хранить и получать не возможно (потому что они просто нигде не хранятся в виде полного значения). Sphinx возвращает не данные, а только ID найденных запиcей, после чего необходимо делать запрос к БД для получения записей по ID.
Если вам необходимо иметь возможность дополнительно производить фильтрацию по полям типа type_id
или вы хотите выводить их без повторного обращения к БД, то вы можете указать их в виде атрибутов в конфигурации: sql_attr_uint
, sql_attr_float
, sql_attr_string
и т.д.
Из источника:
The raw text of Fields is NOT stored, and can NOT be retrieved from the sphinx index. The text is broken into words, hashed, and stored in an inverted index.
Attributes are stored as is in the index. Because the content is stored, they can be used for filtering, sorting and grouping. Can also include the content of the attribute(s) in the result-set.