【问题标题】:Order by relevance using boolean fulltext search使用布尔全文搜索按相关性排序
【发布时间】:2023-03-08 07:32:01
【问题描述】:

我在使用 MySQL 的全文搜索并按相关性顺序返回结果时遇到问题。我必须使用布尔全文搜索,它不会按相关性顺序返回结果。但是,我需要按相关性顺序排列这些结果。如果我尝试在查询末尾添加 order by 子句,则查询结果会使用文件排序,这会使查询非常慢(比没有时慢 1000 倍以上)。我不确定可以做什么。

这是我的查询:

SELECT g.id, MATCH(g.searchable_name) AGAINST ('test*' IN BOOLEAN MODE) AS relevance
 FROM games g
 WHERE MATCH(g.searchable_name) AGAINST ('test*' IN BOOLEAN MODE)
 ORDER BY relevance DESC
 LIMIT 0, 31

提前致谢。

【问题讨论】:

  • relevance 是一个计算列 - 您不能对其应用索引;看到“使用文件排序”就像你会得到的一样好。为什么score 值不能用于订购?
  • 分值?你能解释一下你的意思吗? (我是全文搜索的新手。)
  • 这不正是我正在做的吗?
  • 表格有多少行,searchable_name是不是很多文字?

标签: sql mysql full-text-search


【解决方案1】:

首先你应该考虑IN BOOLEAN MODEdoes not return a score,而是返回二进制(1 = 找到,0 = 未找到):

mysql>SELECT
        topic_id,
        MATCH(topic_text) AGAINST('+tuning' IN BOOLEAN MODE) AS binary
    FROM
        topics_search
    LIMIT 10
+----------+----------+
| topic_id | binary   |
+----------+----------+
| 2        | 0        |
| 4        | 0        |
| 5        | 0        |
| 6        | 1        |
| 7        | 0        |
| 8        | 0        |
| 11       | 0        |
| 12       | 0        |
| 13       | 0        |
| 14       | 0        |
+----------+----------+
10 rows in set (9 ms)

只有自然全文搜索才能生成分数(IN NATURAL LANGUAGE MODE 修饰符没有给出,因为它是默认模式):

mysql>SELECT SQL_NO_CACHE
        topic_id,
        MATCH(topic_text) AGAINST('tuning') AS score
    FROM
        topics_search
    WHERE
        host_id = 1
    ORDER BY
        score DESC
    LIMIT 10
+--------------------+--------------------+
| topic_id           | score              |
+--------------------+--------------------+
| 153257             | 5.161948204040527  |
| 17925              | 4.781417369842529  |
| 66459              | 4.648380279541016  |
| 373176             | 4.570812702178955  |
| 117173             | 4.55166482925415   |
| 167016             | 4.462575912475586  |
| 183286             | 4.4519267082214355 |
| 366132             | 4.348565101623535  |
| 95502              | 4.293642520904541  |
| 29615              | 4.178250789642334  |
+--------------------+--------------------+
10 rows in set (478 ms)

旁注:非常慢,因为score 不能有索引。

所以你需要自然搜索来按分数排序。但自然搜索不支持* 通配符等运算符。现在我们陷入了困境,因为在BOOLEAN 中搜索tunin* 并使用键tuninNATURAL 中进行并行搜索是没有用的,因为没有文本会包含该部分单词。

mysql>SELECT SQL_NO_CACHE
        topic_id,
        MATCH(topic_text) AGAINST('tunin') AS score
    FROM
        topics_search
    WHERE
        MATCH(topic_text) AGAINST('tunin*' IN BOOLEAN MODE)
    AND
        MATCH(topic_text) AGAINST('tunin') > 0
    ORDER BY
        score DESC
    LIMIT 10
Empty set (170 ms)

结论
无法使用通配符进行搜索并按相关性对结果进行排序。

除非您找到一种方法来获取全文索引中被通配符搜索命中的所有单词并在第二个查询中使用它们,或者您根据 LIKE 建立自己的分数并计算其中的单词数量结果行。有趣到打开a new question

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
  • 2012-11-09
  • 2011-08-26
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多