Судя по всему (google & yandex) единственной современной разработкой на ниве поиска с учётом морфологии является phpMorphy. Раньше я использовал RiSearch, но сейчас он похоже почил в бозе. Поэтому буду пробовать новое решение.

Далее привожу полезную запись из блога «Ежовый угол».

На мой взгляд любой поиск по сайту должен обладать русской морфологией. На деле лишь единицы из проектов обладают этой возможностью. Разработчики ссылаются на сложность разработки и я до сего дня думал так же. На деле все оказалось проще – есть готовые словари. К примеру, phpMorphy.

Данный проект незаслуженно забыт программистами, хотя является удобным средством для организации поиска по сайту с учетом морфологии русского, английского или немецкого языков. Словари на каждый язык занимают порядка 2 Мб, сам скрипт – около 20 Кб.

В составе phpMorphy нет инструментария дла работы с базой данных – его придется написать самостоятельно. Но в нем есть самое ценное:

  1. Определение словоформ указанного слова;
  2. Определение корня слова;
  3. Определение начальной формы слова.

Этого хватит слихвой для создания более-менее адекватного поиска. Лично я использовал определение корня слова, а затем каждый корень искал в полях, к примеру, так:

SELECT * FROM `tbl1` WHERE UPPER(`col1`) LIKE ‘%АФИШ%’;

UPPER() используется из-за того, что phpMorphy возвращает все слова в верхнем регистре.

Как я понял, последние версии phpMorphy не работают на PHP4, поэтому стоит начать миграцию на PHP5, хотя если ваши скрипты обновляются более-менее часто, правки будут незначительны.

Подготовка текста

Для обработки введенной пользователем строки удобно пользоваться регулярными выражениями — пример есть на http://php.spb.ru/php/word.html.

Работа со словарями

Для начала нужно скачать требуемые словари (на ваш выбор – русские, английские, немецкие) и готовые модули для работы с ними.

Распаковав модули, у нас получаются файлы со справкой, а также 3 папки: dicts, src и examples. В первую нужно распаковать словари, во второй находятся модули для работы со словарями, а в третьей — пример использования phpMorphy.

Приводить текст примера не буду, вы можете увидеть его самостоятельно. Остановлюсь лишь на его ключевых моментах.
Все, что находится выше строки:

// Hint: in this example words $word_one, $word_two are in russian language(cp1251 encoding)

используется для инициализации словарей. Там ничего не нужно править. Исключение составляют закомментированные строки:

// $codepage = $morphy->getCodepage();
// setlocale(LC_CTYPE, array(’ru_RU.CP1251?, ‘Russian_Russia.1251?));

которые в случае необходимости правите для изменения рабочей кодировки — в немецком это cp1252, а в английском cp1250. Но наверняка вам это не понадобится.

Ниже идет пример работы. У phpMorphy есть 2 режима работы — одиночный (single mode) и блочный (bulk mode). Первый используется для обработки каждого слова по отдельности, второй — для обработки целого массива слов. Остановимся на втором, как наиболее удобном, по крайней мере на мой взгляд.
Для начала задаем входные слова:

$word_one = ‘ПРОВЕРКА’;
$word_two = ‘МОРФОЛОГИЗАТОРА’;

$bulk_words = array($word_one, $word_two);

С помощью phpMorphy мы можем получить у них начальную форму:

$base_form = $morphy->getBaseForm($bulk_words);

получить все словоформы:

$all_forms = $morphy->getAllForms($bulk_words);

или получить корень слова:

$pseudo_root = $morphy->getPseudoRoot($bulk_words);

Что для вас — ваш выбор. Я остановился на определении корня слова — максимально короткий SQL-запрос при аналогичной точности выборки.

В качестве результата возвращается массив, который мы можем использовать для поиска. К примеру, так:

$request_words = array();
$columns = array(”title”, “description”);
foreach($pseudo_root as $group_form)
if($group_form)
foreach($group_form as $one_form)
foreach($columns as $col)
$request_words[] = “UPPER(`”.$col.”`) LIKE ‘%”.$one_form.”%’”;
$request = “SELECT * FROM `tbl1` WHERE (”.join(” OR “,$request_words).”);”;

Дам комментарий — в $columns мы указываем список полей таблицы, по которым производим поиск. В $request, соответственно, формируется окончательный SQL-запрос, который остается лишь выполнить.

PS Попробовать поиск можно на KamWeb.ru. На данный момент результаты сотрируются по рейтингу сайта, но несложно организовать сортировку и по релевантности. Если кому-то нужны полные листинги — пишите.