如何按相关性对MYSQL全文搜索结果进行排序

Posted

技术标签:

【中文标题】如何按相关性对MYSQL全文搜索结果进行排序【英文标题】:How to sort MYSQL fulltext search results by relevancy 【发布时间】:2010-11-04 05:55:08 【问题描述】:

我对 mysql 比较陌生,并且遇到了一个困扰我一段时间的问题。我已经尝试在整个地方搜索答案,但目前还没有找到可接受的解决方案。

这是我目前正在运行的查询,以查找给定搜索词的最佳匹配:

$query="SELECT * from `vocabulary` WHERE translation = 'word' OR translation LIKE '%word%'";

它返回的结果很全面,包括所有相关行。但是,它们没有按任何特定顺序排序,当我在 php 中打印结果时,我希望首先显示完全匹配的那些。像这样:


1 |单词 2 |填字游戏 3 |话 4 |文字匠


非常感谢您的帮助。

-macspacejunkie

【问题讨论】:

更新:感谢大家的帮助!正是我想要的。问候,-macspacejunkie 如果有人帮助了你,请查看他们的回答 【参考方案1】:

LIKE 不是fulltext search。在全文搜索中,MATCH(...) AGAINST(...) 返回一个可以大致近似为相关性的匹配分数。

【讨论】:

【参考方案2】:

您可以通过创建全文索引然后匹配您的搜索词来获得良好的相关性搜索。

所以这样的事情应该可以工作。

ALTER TABLE `vocabulary` ADD FULLTEXT INDEX `SEARCH`(`translation`);

SELECT *, MATCH(translation) AGAINST ('+word' IN BOOLEAN MODE) AS relevance 
FROM `vocabulary`
WHERE MATCH(translation) AGAINST ('+word' IN BOOLEAN MODE)
ORDER BY relevance DESC

更多信息可以在MySQL Reference Manual找到。

【讨论】:

当 MATCH 命令用于 WHERE 子句时,MySQL 会自动将行从相关性从高到低排序。 谢谢你,Rich Adams 和 ejunker 的这个。两者都非常好。我有一个客户在搜索相关性方面苦苦挣扎,这是一个很大的帮助。 @ejunker 那太好了。你能指出这个的参考吗?这也适用于布尔模式?谢谢。 @RichAdams 此查询是否返回 OP 要求的单词、wordsmith 等结果?我认为你需要使用 word*【参考方案3】:
SELECT * from vocabulary 
WHERE translation like 'word'  
union all
SELECT * from vocabulary 
WHERE translation LIKE '%word%' and translation not like 'word'  

将首先列出完全匹配

【讨论】:

这是在大表中做事的一种非常糟糕的方式。考虑使用FULLTEXT 搜索更快的查询【参考方案4】:

我一直在研究同样的问题,但还没有找到适合我情况的完美答案,但这可能对你有用。我对全文搜索也很陌生,所以任何专家也可以帮助我。

我在 select 中执行两个 MATCH() AGAINST() 语句,并将每个语句的分数组合起来形成总相关性。分配不同的乘数可以让我配置每组结果的重要性。

我的第一个 MATCH() 将使用双引号检查文字(或精确)搜索词。 我的第二场比赛会正常检查。我对第一个匹配项应用了更高的乘数,因此如果找到它应该具有更高的相关性值。

类似的东西。

SELECT *, ((MATCH(indexes) AGAINST ('"search_terms"' IN BOOLEAN MODE) * 10)  
           + (MATCH(indexes) AGAINST ('search_terms' IN BOOLEAN MODE) * 1.5)) AS relevance  
FROM ...
WHERE ...  
      AND (MATCH (indexes) AGAINST ('"search_terms"' IN BOOLEAN MODE) > 0  
           OR MATCH (indexes) AGAINST ('search_terms' IN BOOLEAN MODE) > 0)  
      ...
ORDER BY relevance DESC

如果您使用 EXPLAIN 检查查询的工作方式,您应该会发现,由于 MySQL 的工作方式,额外的 MATCH() AGAINST() 子句实际上并没有增加查询的任何开销。

【讨论】:

【参考方案5】:

您的查询只需稍作修改即可获得您要查找的订单。

SELECT * 
FROM vocabulary
WHERE translation LIKE '%word%'
ORDER BY translation <> 'word', translation;

如果translation 正好是'word',它将位于结果的顶部。这是因为translation &lt;&gt; 'word' 将是 0 当有一个 exact match 出现在 1 之前,它将为所有其他结果返回.由于, translation,其余结果将按字母顺序排序。

此查询避免像所选答案对其UNION 那样进行两次查询。此外,您的查询不需要translation = 'word' OR translation LIKE '%word%',因为后半部分将始终执行并且是第一部分的超集。

对于那些寻找使用实际全文搜索的答案的人,请查看其他更受好评的答案。

【讨论】:

以上是关于如何按相关性对MYSQL全文搜索结果进行排序的主要内容,如果未能解决你的问题,请参考以下文章

Mysql全文搜索,自然语言模式:按“亲密度”排序

搜素引擎全文检索原理

全文搜索按相关性分数排序

PostgreSQL 中的高效全文搜索,在另一列上排序

全文搜索基本原理(倒排索引搜索结果排序)

mysql全文搜索,多个关键词权重排序