mysql оценка релевантности полнотекстового поиска не верна - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть полнотекстовый индекс в столбце имени. Когда я выполняю поиск ficus nit 15g* в логическом режиме, я ожидаю, что Ficus Nitida - Indian Laurel Fig будет лучшим результатом. Но все 3 элемента имеют одинаковый показатель релевантности.

Есть ли способ получить более релевантный результат вверху?

Ниже приведен запрос с результатами.

mysql> SELECT phppos_items.name, MATCH (phppos_items.name) AGAINST ('ficus nit 15g*' IN BOOLEAN MODE) as rel FROM `phppos_items` WHERE MATCH (phppos_items.name) AGAINST ('ficus nit 15g*' IN BOOLEAN MODE)  ORDER BY `rel` DESC;
+-----------------------------------------+--------------------+
| name                                    | rel                |
+-----------------------------------------+--------------------+
| Ficus Benjamna - Weeping Banyon - 15gal | 0.0984337329864502 |
| Ficus Rubignosa - Rusty Leaf Fig 15gal  | 0.0984337329864502 |
| Ficus Nitida - Indian Laurel Fig 15gal  | 0.0984337329864502 |
+-----------------------------------------+--------------------+
3 rows in set (0.00 sec)

РЕДАКТИРОВАТЬ : попробованный ответ

mysql> SELECT phppos_items.name, MATCH (phppos_items.name) AGAINST ('ficus* nit* 15g*' IN BOOLEAN MODE) as rel FROM `phppos_items` WHERE MATCH (phppos_items.name) AGAINST ('ficus* nit* 15g*' IN BOOLEAN MODE)  ORDER BY `rel` DESC;
+-----------------------------------------+--------------------+
| name                                    | rel                |
+-----------------------------------------+--------------------+
| Ficus Benjamna - Weeping Banyon - 15gal | 0.1812381148338318 |
| Ficus Rubignosa - Rusty Leaf Fig 15gal  | 0.1812381148338318 |
| Ficus Nitida - Indian Laurel Fig 15gal  | 0.1812381148338318 |
+-----------------------------------------+--------------------+
3 rows in set (0.00 sec)

1 Ответ

1 голос
/ 06 февраля 2020

Если вы не используете подстановочный знак, полнотекстовый поиск соответствует (и получает оценки) только одинаковым словам. Nitida и nit - это разные слова, и они не влияют на оценку и не будут фактически найдены, например, match(...) against ('nit') не вернет ни одну из ваших строк выборки.

В зависимости от ваших точных требований, это может быть уже достаточно добавить подстановочный знак к каждому поисковому запросу, который будет и находить, и оценивать отдельные слова, например, использовать

match(...) against ('ficus* nit* 15g*' IN BOOLEAN MODE) 

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

match(...) against ('>ficus >nit >15g ficus* nit* 15g*' IN BOOLEAN MODE) as rel

, используя > <-operator </a>:

Эти два оператора используются для изменения вклада слова в значение релевантности, назначенное строке. Оператор> увеличивает вклад, а оператор <уменьшает его. </p>

Таким образом, точное совпадение с nit даст больше, в то время как неточное совпадение с Nitida все же добавит несколько очков. Следует отметить, что релевантность основана на редкости слова, поэтому редкое, но подстановочное слово может быть все же более релевантным, чем обычное, но точное совпадение.

Вы получаете больше контроля с помощью пользовательского веса, используя что-то вроде

match(...) against ('ficus nit 15g' IN BOOLEAN MODE) * 10 
+ match(...) against ('ficus* nit* 15g*' IN BOOLEAN MODE) as rel

Вы можете делать оценку независимо от поиска, но вы можете / должны решить, хотите ли вы найти Nitida, если вы введете Nit, или вы просто хотите дать это лучший результат (но найти его, только если есть точное совпадение с другим поисковым термином). Например, вы бы использовали WHERE MATCH(...) AGAINST ('ficus nit 15g*' IN BOOLEAN MODE) или WHERE MATCH(...) AGAINST ('ficus* nit* 15g*' IN BOOLEAN MODE).

...