我对MYSQL比较陌生,并且有一个问题一直困扰着我。我已经尝试使用谷歌搜索到答案,但目前尚无法找到可接受的解决方案。
以下是我目前正在运行的查询,以查找给定搜索字词的最佳匹配项:
$query="SELECT * from `vocabulary` WHERE translation = 'word' OR translation LIKE '%word%'";
它返回的结果是全面的,因为它们包含所有相关的行。但是,它们没有按任何特定顺序排序,我希望在用PHP打印结果时首先显示完全匹配的那些。像这样:
1 |单词< -exact match
2 |填字游戏< - 按字母顺序排序的部分匹配/
3 |也就是说
4 |文字匠
非常感谢您的协助。
-macspacejunkie
答案 0 :(得分:29)
LIKE不是fulltext search。在全文搜索中,MATCH(...) AGAINST(...)
会返回一个匹配的分数,可以大致近似为相关性。
答案 1 :(得分:22)
您可以通过创建全文索引然后匹配搜索字词来获得良好的相关性搜索。
所以这样的事情应该有用。
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。
中找到答案 2 :(得分:15)
SELECT * from vocabulary
WHERE translation like 'word'
union all
SELECT * from vocabulary
WHERE translation LIKE '%word%' and translation not like 'word'
将首先列出完全匹配
答案 3 :(得分: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()AGAINST()子句实际上并没有因为MySQL的工作方式而给查询添加任何开销。
答案 4 :(得分:2)
您的查询只需要稍加修改即可获得您正在寻找的订单。
SELECT *
FROM vocabulary
WHERE translation LIKE '%word%'
ORDER BY translation <> 'word', translation;
如果translation
正好是'word'
,它将位于结果的顶部。这是因为当{em>完全匹配出现在 1 之前,translation <> 'word'
0 将会返回所有的 1 其他结果。由于, translation
。
此查询可避免使用UNION
等选定答案等两个查询。此外,您的查询不需要translation = 'word' OR translation LIKE '%word%'
,因为后半部分将始终执行,并且是第一部分的超集。
对于那些寻找使用实际全文搜索的答案的人,请参阅其他更高评价的答案。