【问题标题】:mysql fulltext search relevancy score not rightmysql全文搜索相关性得分不正确
【发布时间】:2026-01-07 04:20:03
【问题描述】:

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

【问题讨论】:

    标签: mysql full-text-search


    【解决方案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 为他的问题提供了非常可靠的解决方案,但原始发帖人放弃了他的帖子。