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" 个案例进行了排名。 (我扩展了你的测试用例以增加长度。)
我正在 运行 针对 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" 个案例进行了排名。 (我扩展了你的测试用例以增加长度。)