MySQL FullText search - логическое условие поиска с минимальным размером токена означает, что результаты не возвращаются - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть таблица школьных данных с полнотекстовыми индексами по столбцам, в Mysql 5.6.33.

innodb_ft_min_token_size установлено на 3 (по умолчанию). Это самое маленькое слово, которое индексируется.

Если я ищу почтовый индекс, где одна из частей меньше этого размера, то поиск дает оценку 0 для записи с этим почтовым индексом:

mysql> SELECT record_id, keywords, 
    -> MATCH (keywords) AGAINST ("+l4 +0uf" IN BOOLEAN MODE) as score
    -> FROM squirrel_schools 
    -> WHERE record_id = 137212;
+-----------+---------------------+-------+
| record_id | keywords            | score |
+-----------+---------------------+-------+
|    137212 | l4 0uf l40uf 137212 |     0 |
+-----------+---------------------+-------+
1 row in set (0.00 sec)

Итак, мы видим, что оно содержит оба обязательных слова в поле ключевых слов, но получает оценку 0.

Это, кажется, из-за переменной innodb_ft_min_token_size, потому что если я вместо этого изменю почтовый индекс и поисковый термин на "L4X 0UF", тогда он будет работать нормально. Так что там есть двухбуквенное слово, которое его ломает.

Теперь я бы понял, если бы он проигнорировал бит "+ L4", потому что он меньше минимального размера токена: например, если он проигнорировал "+ L4" и просто дал оценку к этой записи, основанной на сопоставлении «+ 0UF», тогда это, по крайней мере, будет соответствовать цели получения минимального размера токена.

Но позволить ему прервать поиск, чтобы он не дал оценку чему-либо с этим словом, кажется действительно неправильным.

Может кто-нибудь объяснить, делаю ли я здесь что-то не так, или я неправильно понял, как должен работать минимальный размер токена?

РЕДАКТИРОВАТЬ - Я понимаю, что я могу изменить переменную innodb_ft_min_token_size, например, на 2 вместо 3, и это может решить этот конкретный поиск. Но я хотел бы понять реальную логику этого.

1 Ответ

1 голос
/ 12 мая 2019

MyISAM выручит вас, но InnoDB говорит:

"Вы потребовали (через +) включить 14, но, поскольку я не проиндексировал его, я не нашел его. Поэтому строка исключена."

Это спорно, является ли это «право», но это то, что он делает.

Обходной путь, который я использую, - не ставить + перед слишком короткими строками. Если я действительно хочу заставить 14 существовать, тогда я добавляю что-то вроде

AND col REGEXP "[[:<:]]14[[:>:]]"

Сначала будет выполняться MATCH (быстрее), а затем дважды проверяться с помощью REGEXP.

Забавные фигурные скобки - это «границы слов». Так что это совпадает, когда 14 встречается как «слово» где-нибудь внутри col. Он не будет соответствовать, например, 146, но будет соответствовать Address: 14 Main st. или обычному 14.

...