PHP в деталях



         

По следам поиска в "деталях" - релевантность



25.9.2001

Помнится в статье "Безопасный и удобный поиск" была такая фраза:

"Наверное, в том же Яндексе все видели ссылочку "сортировать по релевантности". Это оно и есть. Сортировка результатов по количеству совпадений слов. Отчасти, кстати, такая сортировка снимает проблему обработки логики поиска. Но с БД MySQL делать такую сортировку очень сложно. Надо сперва выбрать, где есть все слова, потом записи, где разные слова (исключив предыдущие). Если у вас постраничный вывод? то вообще дело труба!"

На данный момент (начиная с MySQL 3.23.23) это не совсем так. Можно сказать, что с точностью до наоборот ? с БД MySQL делать такую сортировку очень просто с использованием FULLTEXT полей.

Для вывода результатов поиска по релевантности необходимо:

1. Требуемые поля VARCHAR, либо любые из разновидностей полей TEXT (SMALLTEXT, MEDIUMTEXT и т.п.) сделать ключами FULLTEXT:

ALTER TABLE table ADD FULLTEXT(field)

Или во всеми любимом phpMyAdmin'е, который я слегка подправил для работы с FULLTEXT полями (архив прилагается ? вдруг кому пригодится).

2. Дальше ? еще проще:

$query = "SELECT *, MATCH field AGAINST ('$searchwords') as relev FROM table ORDER BY relev DESC"

Далее можно навешивать всякие LIMIT'ы и прочее для удобного вывода.

3. Все::)

Заметки:

1. По умолчанию установлен поиск слов, содержащих не менее 4 символов. Правится установкой #define MIN_WORD_LEN 4 в исходнике ft_static.c, хотя на мой взгляд править это не нужно.

2. Недоступны символы % в поисковой фразе, слова в поисковой фразе парсятся с использованием списка разделетелей.

3. Список разделителей слов правится в исходнике ft_static.c.

4. Необходимо минимум десяток записей в таблице для начала вычисления релевантности.

5. Нельзя поле relev использовать в клаузе WHERE:

SELECT *, MATCH field AGAINST ('$searchwords') as relev FROM table WHERE relev>0 ORDER BY relev DESC

хотя можно:

SELECT *, MATCH field AGAINST ('$searchwords') as relev FROM table WHERE MATCH field AGAINST ('$searchwords')>0 ORDER BY relev DESC




Содержание  Назад  Вперед