Простой поиск на PHP с учетом различных форм слова



Для поиска в тексте с учетом различных форм слова (например "искать", "искал") существует несколько способов. Существуют варианты, в которых строятся все возможные формы искомого слова. Мы же рассмотрим способ, при котором от искомого слова отбрасывается суффикс и/или окончание (например "искал" превратится в "иск").
 
Для этого нам потребуется так называемый стеммер, класс Lingua_Stem_Ru, написанный на PHP. Он довольно небольшой, его просто найти в интернете по названию. Единственный минус данного решения это то, что оно не учитывает такие формы слова как например "ищу" для искомого слова "искал". Причина здесь в разных корнях слов.
 
Итак, подключаем и создаем стеммер:
require_once('stemmer.php');
$stemmer = new Lingua_Stem_Ru();
 
Очистим строку поиска $s от лишних символов (в данном случае это символы "-!?.,+—", но вы можете изменить их набор), и разобьем строку по словам, используя пробелы в качестве разделительных символов между словами:
 
$tmp = preg_replace('{[-!?.,+—]}', ' ', $s);
$tmp = preg_split('{ +}', $tmp);
 
Далее, построим массив $search_words, который будет содержать слова без окончаний, при этом, слова из массива поисковых слов $tmp, короче 3-х символов отбрасываем. Для построения слова без окончания используется функция $stemmer->stem_word(слово):
 
for($i = 0; $i < count($tmp); $i++)
    if(strlen($tmp[$i]) > 2)
        $search_words[] = $stemmer->stem_word($tmp[$i]);
 
Предположим, что мы ищем в поле `text` таблицы `table`, тогда следующий запрос извлечет все записи, в которых `text` содержит хоть одно из слов в массиве $search_words:
 
$query = 'SELECT * FROM `table` WHERE ';
for($i = 0; $i < count($search_words); $i++)
{
    $query .= " (`text` LIKE '".$search_words[$i]."%') ";
    if($i < count($search_words) - 1)
        $query .= 'OR';
}
 
В данном случае мы использовали конструкцию LIKE 'искомое_слово%', т. е. если мы искали слово "про", в результатах будут слова "про", "проблем", "проведение" (отличающиеся только окончаниями слов) но не слово "опрос". Для варианта "опрос" конструкция должна выглядеть так: LIKE '%искомое_слово%'.
 
Подробнее про LIKE можно прочитать в документации к mysql.





Добавить комментарий

Логин:
Пароль:
Проверочное число: