MySQL InnoDB FULLTEXT搜索短语搜索排名

时间:2020-02-27 09:58:17

标签: mysql sql full-text-search innodb

我正在对InnoDB表运行FULLTEXT搜索,查找短语而不是单独的关键字。例如。搜索“ foo bar”作为两个词的短语,而不是分别搜索“ foo”和“ bar”。

这是我的测试数据:

+----+-------------------------------------------------------------------------------+
| id | content                                                                       |
+----+-------------------------------------------------------------------------------+
|  1 | example foo text bar                                                          |
|  2 | default value foo foo server                                                  |
|  3 | default value foo foo server bar foo test                                     |
|  4 | process foo bar potato integer text bar bar content foo foo value bar foo foo |
|  5 | foo bar demo string value foo bar music foo bar most foo bar                  |
+----+-------------------------------------------------------------------------------+

这是我的测试查询:

SELECT *, MATCH(content) AGAINST ('"foo bar"' IN BOOLEAN MODE) AS score
FROM test
WHERE MATCH(content) AGAINST ('"foo bar"' IN BOOLEAN MODE)

问题是结果:

+----+-------------------------------------------------------------------------------+--------------------+
| id | content                                                                       | score              |
+----+-------------------------------------------------------------------------------+--------------------+
|  4 | process foo bar potato integer text bar bar content foo foo value bar foo foo |  0.948742687702179 |
|  5 | foo bar demo string value foo bar music foo bar most foo bar                  | 0.8314893841743469 |
+----+-------------------------------------------------------------------------------+--------------------+

如您所见,第5行包含短语“ foo bar”四次,而第4行仅包含一次,但第4行的排名高于5。看起来该排名似乎忽略了短语要求。

有人知道如何使它正常工作吗?

2 个答案:

答案 0 :(得分:0)

我怀疑这是短语的怪癖。以下documentation属于我所见过的最不一致的语言之一:

包含在双引号(“)字符中的短语匹配 仅包含按字面意思输入的短语的行。 全文引擎将短语分解为单词,并在其中进行搜索 单词的FULLTEXT索引。非单词字符不必是 完全匹配:词组搜索仅要求匹配包含 与短语完全相同的单词,并且顺序相同。

第一句话与其余说明直接冲突。我强调了我认为重要的部分。

所以,我推测。 MySQL在单词级别进行短语匹配。因此,结果中会有更多的“ foo”和“ bar”,而没有“ foo bar”。还有一些额外的机制可以确保该对实际上位于结果集中,但这不会影响得分。

可以做的一件事是您自己的订购:

order by length(content) - length(replace(content, 'foo bar', '')) desc

这会在内容中明确查找“ foo bar”,并按该值排序。

答案 1 :(得分:0)

我认为(没有任何文档参考)排名也取决于整个文本的长度。人们可以争论很多事情;尽量不要将期望值过高。

我尝试了7个版本的MySQL / MariaDB,并获得了6套不同的“得分”。因此,我强烈建议您不要非常认真地对待任何分数。但是,他们确实以相同顺序对4个“ foo bar”案例进行了排名。 (我扩展了您的测试用例,以进一步改变长度。)