mysql全文搜索相关性得分不正确

Posted

技术标签:

【中文标题】mysql全文搜索相关性得分不正确【英文标题】:mysql fulltext search relevancy score not right 【发布时间】:2020-05-21 20:29:11 【问题描述】:

我在名称列上有一个全文索引。当我在布尔模式下搜索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】:

除非您使用通配符,否则全文搜索仅匹配(并评分)相同的单词。 Nitidanit 是不同的词,既不会影响分数,也不会真正被发现,例如match(...) against ('nit') 不会返回您的任何示例行。

根据您的具体要求,为每个搜索词附加一个通配符可能已经足够了,这将查找和评分部分词,例如使用

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

这不会使完全匹配比部分匹配更有价值,因此您还可以自定义分数,例如与nitnit* 匹配,但使用类似

的方式将精确匹配权重更高
match(...) against ('>ficus >nit >15g ficus* nit* 15g*' IN BOOLEAN MODE) as rel

使用> <-operator:

这两个运算符用于更改单词对分配给行的相关值的贡献。 > 运算符增加贡献,

这样,与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)

【讨论】:

通配符到处都没有解决它。我提出了疑问。 我描述的行为是它应该如何工作,并且适合您的原始问题。请参阅此fiddle。现在困难的部分开始弄清楚对你来说有什么不同。您能否检查您是否对name 使用二进制或cs 排序规则,使其区分大小写(例如,添加您的表描述)?你可以重新检查你复制和粘贴的所有内容 1:1 (没有小写/大写的区别,...)?您可以尝试在您的服务器上运行我的小提琴代码(使用调整后的表名)吗?你能在小提琴上重现你的行为吗? 尽管 Solarflare 为他的问题提供了非常可靠的解决方案,但原始发帖人放弃了他的帖子。

以上是关于mysql全文搜索相关性得分不正确的主要内容,如果未能解决你的问题,请参考以下文章

Mysql全文搜索跨多个表的相关性

MySQL全文搜索结果相关性

MySQL 全文搜索以布尔模式按相关性排序

如何按相关性对MYSQL全文搜索结果进行排序

如何操纵 MySQL 全文搜索相关性以使一个字段比另一个字段更“有价值”?

Mysql全文搜索,自然语言模式:按“亲密度”排序