2009-06-19 91 views
22

我对MYSQL相对较新,并且遇到了一段时间以来一直困扰我的问题。我已经试过Google的搜索结果,但仍然无法找到可接受的解决方案。如何根据相关性对MYSQL全文搜索结果进行排序

这里是我当前正在运行的找到最佳匹配对于给定的搜索词的查询:

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

它所返回的结果是全面的,因为它们包含所有相关行。但是,它们没有按照任何特定的顺序排序,并且我想在PHP中打印结果时首先显示完全匹配的结果。像这样:


1 | word < -exact match
2 |字谜< - 部分比赛按字母/顺序排列/
3 |字
4 |语言大师


预先感谢您对我付出的援助。

-macspacejunkie

+0

更新:谢谢大家的帮助!正是我在找的东西。 Regards, -macspacejunkie – user125591 2009-06-19 11:38:00

+0

如果有人帮助过您,请检查他们的答案 – Jason 2009-06-19 16:45:53

回答

14
SELECT * from vocabulary 
WHERE translation like 'word' 
union all 
SELECT * from vocabulary 
WHERE translation LIKE '%word%' and translation not like 'word' 

会列出确切的匹配第一

+1

这是在大型表格中执行操作的非常糟糕的方式。考虑使用`FULLTEXT`搜索更快的查询 – OverCoder 2016-09-02 21:26:55

28

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

21

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

所以像这样的东西应该工作。

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找到。

5

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

我在select中做了两次MATCH()AGAINST()语句,并将每个分数合并以形成总体相关性。分配不同的乘数允许我配置每组结果的导入。

我的第一次MATCH()将检查使用双引号的文字(或确切)搜索词 我的第二次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功能显示查询是如何工作的,你应该发现,额外的MATCH()反对()子句不实际的查询由于MySQL的工作方式增加任何额外开销。

2

您的查询只需要一点点修改让你要找的顺序。

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

如果translation正是'word',它会在结果顶部。这是因为translation <> 'word'将会是当有完全匹配它会在之前被返回所有其他结果。剩下的结果将按照字母顺序后,由于, translation的排序。

此查询避免做两个查询,如选择的答案确实与它的UNION。此外,您的查询不需要translation = 'word' OR translation LIKE '%word%'下半年以来就一定会执行,并且是第一部分的超集。

对于那些正在寻找使用实际全文搜索的答案,请参阅其他更高回答的答案。

相关问题