У хостера Beget.ru при любом тарифе хостинга можно подключить поисковую программу Sphinx в разделе «Сервисы». Чтобы оно заработало, нужно правильно прописать конфиг. Далее, пример минимального конфига.
Исходные данные
База данных не обязательно должна быть на том же хостинге, где и сервис, но для простоты создаём там же. Пусть она содержит таблицу «product».
id | name | category_id | producer_id |
Файл конфига
source catalog
{
type = mysql
sql_host = localhost
sql_user = db_user
sql_pass = db_pass
sql_db = db_name
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query = \
SELECT * \
FROM product
sql_attr_uint = category_id
sql_attr_uint = producer_id
}
index catalog
{
source = catalog
path = /var/lib/sphinx/data/catalog
morphology = stem_enru
min_word_len = 1
}
indexer
{
mem_limit = 240M
}
searchd
{
log = /var/log/sphinx/searchd.log
query_log = /var/log/sphinx/query.log
pid_file = /var/run/sphinx/searchd.pid
listen = 9312
listen = 9306:mysql41
}
Здесь, db_user, db_pass и db_name нужно заменить на реальные.
path, log, query_log и pid_file при сохранении конфига подменяются сервисом, как я понял.
Результаты
Получить данные можно так. Установить Yii2 и его компонент Sphinx. Далее, в контроллере добавляем:
/* Это наверх */
use app\models\Product;
use yii\sphinx\Query;
use yii\db\Expression;
/* А это в экшен */
$query = new Query();
$rows = $query->from('catalog')
->match(new Expression(':match', ['match' => '@(name) ' . Yii::$app->sphinx->escapeMatchValue($_GET['s'])]))
->all();
$result = [];
foreach ($rows as $row) {
$result[] = Product::findOne(['id' => $row['id']]);
}
Здесь, catalog — это имя индекса, name — название колонки в таблице.
Соответственно, если в url добавить get параметр ?s=мочалка
будет результат.
Sphinx — поиск без пробелов
Что если в базе есть некоторая запись, содержащая строку «Доктор Ватсон», и требуется её отдать по запросу «докторватсон». То есть, запрос вводится без пробелов. Как искать?
Вариант, индексировать контент без пробелов. При этом, такой индекс должен дополнять обычный, иначе поиск по формам отдельных слов не будет работать. Таким образом, размер индекса увеличивается. Плохо, с точки зрения производительности и экономии ресурсов, но решает задачу.phone case picture1:1 replica watches
Пример:
source default_index
{
type = mysql
sql_host = *******
sql_user = *******
sql_pass = *******
sql_db = ********
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query = \
SELECT * \
FROM product
sql_attr_uint = category_id
sql_attr_uint = producer_id
}
source without_spaces
{
type = mysql
sql_host = *******
sql_user = *******
sql_pass = *******
sql_db = ********
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query = \
SELECT * \
FROM product
sql_attr_uint = category_id
sql_attr_uint = producer_id
}
index default_index
{
source = default_index
type = plain
path = /var/lib/sphinx/data/default_index
morphology = stem_enru
min_word_len = 1
charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+2E, U+002A
html_strip = 1
min_prefix_len = 3
min_infix_len = 0
expand_keywords = 1
}
index without_spaces
{
source = without_spaces
type = plain
path = /var/lib/sphinx/data/without_spaces
morphology = stem_enru
min_word_len = 1
charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+2E, U+0020, U+002A
html_strip = 1
min_prefix_len = 3
min_infix_len = 0
expand_keywords = 1
ignore_chars = U+0020
}
indexer
{
mem_limit = 240M
}
searchd
{
log = /var/log/sphinx/searchd.log
query_log = /var/log/sphinx/query.log
pid_file = /var/run/sphinx/searchd.pid
listen = 9312
listen = 9306:mysql41
}