FULLTEXT поиск и короткие слова

Задача
FULLTEXT поиск по коротким словам не возвращает записей.

Решение
Измените значение параметра минимальной длины слова для механизма индексирования.

Обсуждение
В тексте, подобном KJV, некоторые слова имеют особое значение, например «Бог» или «грех». Но если вы, работая с сервером MySQL 3.23, выполните FULLTEXT поиск этих слов в таблице kjv, то обнаружите любопытный результат – ни того, ни другого слова как будто никогда и не было в тексте:

SELECT COUNT(*) FROM kjv WHERE MATCH(vtext) AGAINST('God');


+------------ +
| COUNT(*) |
+ ------------+
| 0 |
+ ------------+

mysql> SELECT COUNT(*) FROM kjv WHERE MATCH(vtext) AGAINST('sin');

+ ------------+
| COUNT(*) |
+ ------------+
| 0 |
+ ------------+

Одно из свойств индексатора – игнорирование «слишком общих» слов (то есть слов, присутствующих более чем в половине записей). Так, из индекса удаляются слова типа «the» и «and», но в данном случае мы имеем дело с чемто иным. Давайте сосчитаем общее количество записей и (при помощи шаблонов SQL) количество записей, содержащих каждое из слов:1

SELECT COUNT(*) AS 'total verses',
    > COUNT(IF(vtext LIKE '%God%',1,NULL)) AS 'verses containing "God"',
    > COUNT(IF(vtext LIKE '%sin%',1,NULL)) AS 'verses containing "sin"'
    > FROM kjv;


+-------------- + -----------------------------+---------------------------- +
| total verses | verses containing "God" | verses containing "sin" |
+-------------- +----------------------------- + ----------------------------+
| 31102 | 4118 | 1292 |
+-------------- + -----------------------------+ ----------------------------+

Ни одно из слов не присутствует более чем в половине стихов, так что полно текстовый поиск не удался не изза частого употребления слов. Причина в том, что по умолчанию в индексы не включаются слова, длина которых меньше четырех символов. Если вы работаете с сервером MySQL 3.23, то вам ничего не удастся с этим поделать (по крайней мере, ничего более простого, чем обращение к исходным текстам MySQL с их повторной компиляцией).

Но начиная с версии MySQL 4.0 минимальная длина слова является настраиваемым параметром, который можно изменить, задав переменную сервера ft_min_word_len. Например, чтобы включать в индекс слова, содержащие три и более символов, добавьте строку set variable в группу
 файла /etc/my.cnf (или другого файла, в котором вы храните настройки сервера):

[mysqld]
setvariable = ft_min_word_len=3

Сохраните изменения, перезапустите сервер и пересоздайте индекс FULLTEXT, чтобы новое значение вступило в силу: 

[SQL]ALTER TABLE kjv DROP INDEX vtext;
ALTER TABLE kjv ADD FULLTEXT (vtext);


Давайте посмотрим, включает ли новый индекс короткие слова:

SELECT COUNT(*) FROM kjv WHERE MATCH(vtext) AGAINST('God');


+------------ +
| COUNT(*) |
+ ------------+
| 3878 |
+ ------------+

mysql> SELECT COUNT(*) FROM kjv WHERE MATCH(vtext) AGAINST('sin');

+ ------------+
| COUNT(*) |
+ ------------+
| 389 |
+ ------------+

Так то лучше!
Но почему запрос с MATCH() находит 3878 и 389 записей, в то время как при веденный ранее запрос с LIKE нашел 4118 и 1292 записей? Поиск по образцу с помощью LIKE ищет соответствующие подстроки, а поиск FULLTEXT, осуществляемый MATCH(), ищет только целые слова.
  FULLTEXT, поиск
Похожие новости:
Добавлено: 12 Июля 2018 08:23:07 Добавил: Андрей Ковальчук
Добавить