MySQL 短语搜索的 InnoDB FULLTEXT 搜索排名

MySQL InnoDB FULLTEXT search rankings for phrase searches

我正在 运行 针对 InnoDB table 进行全文搜索,查找短语而不是单独的关键字。例如。搜索 "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。看起来好像排名忽略了短语要求。

有谁知道如何让它正常工作?

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

A phrase that is enclosed within double quote (") characters matches only rows that contain the phrase literally, as it was typed. The full-text engine splits the phrase into words and performs a search in the FULLTEXT index for the words. Nonword characters need not be matched exactly: Phrase searching requires only that matches contain exactly the same words as the phrase and in the same order.

第一句直接和后面的解释冲突了。我已经突出显示了我认为重要的部分。

所以,我会推测。 MySQL 在单词 级别进行短语匹配 。因此,结果中有更多 "foo" 和 "bar"——没有 "foo bar" 会增加分数。有一些额外的机制可以确保该对确实在结果集中,但这不会影响分数。

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

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

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

我认为(没有任何文档参考)排名也取决于总文本的长度。有很多事情可以说应该考虑在内;尽量不要将您的期望定得太高。

我尝试了 7 个版本的 MySQL/MariaDB,得到了 6 套不同的 "scores"。因此,我强烈建议不要非常认真地对待任何 单个 分数。然而,他们确实以相同的顺序对 4 "foo bar" 个案例进行了排名。 (我扩展了你的测试用例以增加长度。)