Приветствую вас! Сегодня мы обсудим настройку sphinx для посимвольного поиска по префиксам слов.
Проблема
Передо мной была поставлена задача реализовать "живой" поиск, т.е. поиск с обновлением результатов по мере ввода. Однако, настроив sphinx привычным образом было замечено что поиск осуществляется не совсем корректно, а именно ведется по целым словам или их формам. Например, при поиске слова "деревья" я начинаю вводить "д" и получаю много результатов, затем я ввожу вторую букву "е" и результат пропадает. Только после ввода части "деревь" я получаю необходимый результат. Давайте решим эту проблему!
Конфигурация Sphinx
Нас интересует блок index конфигурационного файла. Здесь необходимо добавить две директивы к уже существующим:
- enable_star = 1 - включает поиск с использованием оператора "*", т.е. введя поисковую фразу "дере*" мы получим совпадение с словом "деревья"
- min_prefix_len = 1 - минимальную длину префикса устанавливаем в один символ, для живого поиска это необходимое требование, чтобы пользователь мог видеть результат уже с первого введенного символа
После этих изменений блок index моего конфигурационного файла принял следующий вид:
index testIndex
{
# Источник, который будет хранить данный индекса
source = testSource
path = /var/sphinx
# Тип хранения аттрибутов
docinfo = extern
mlock = 0
# Используемые морфологические движки
morphology = stem_enru, soundex, metaphone
# Кодировака данных из источника
charset_type = utf-8
enable_star = 1
min_prefix_len = 1
}
Работа с клиентом sphinx
Далее нам необходимо преобразовывать запрос пришедший от пользователя, добавляя к каждому слову знак "*" в конце. У меня получилось что-то вроде этого:
<?php
// ...
$client = new SphinxClient;
// $q - запрос пришедший от пользователя
$words = explode(' ', $q);
$query = '';
foreach ($words as $word){
$word = trim($word);
if (strlen($word))
$query .= $word . '* ';
}
$result = $client->Query($query, 'tracksIndex');
После внесения всех этих изменений живой поиск должен работать так, как ожидается. Если у вас возникнут вопросы - задавайте их в комментариях ниже.