admin

按一组关键字的出现对sql结果进行排序

sql

我正在尝试为我的网站做一个小的搜索引擎。首先,用户输入一些关键字,然后转到使用此代码的结果页:

$result = array();
$keyword_tokens = explode(' ', $keywords);
$keyword_tokens = array_map(
    function($keywords) {
        return mysql_real_escape_string(trim($keywords));
    }, 
    $keyword_tokens
);
$sql = "SELECT * FROM search_table WHERE concat(title, description) LIKE '%";
$sql .= implode("%' OR concat(title, description) LIKE '%", $keyword_tokens) . "%' ORDER BY instr(description, '$keywords') DESC, instr(title, '$keywords') DESC";
$result=mysql_query($sql);

此代码允许搜索用户请求的关键字并按$ keywords进行排序,因此可以按关键字组的完整确切字符串进行排序…

我想做的是按照每个关键字的出现次数排序结果。例如,如果我的sql结果中的一行包含5个关键字,而其他3个关键字等,则应首先出现5个关键字。我正在搜索按更多匹配关键字对结果进行排序。

希望一切都是可以理解的…

帮助将不胜感激!


阅读 255

收藏
2021-07-01

共1个答案

admin

关于MySQL的美好之处,取决于您的观点。它以认为您希望对其进行处理的方式对待数据。 1 + '1'?很明显,您想将字符串当作数字对待,因此它很高兴为您执行加法。

也适用于布尔操作数(只需要注意运算符的优先级)。 (a like '%foo%') + (a like '%bar%')识别数字上下文,将布尔结果true视为1和布尔结果false视为0-本质上是为您计算关键字匹配项。

你怎么用呢?把你的where条款,替换所有or+,并确保每个单独like的语句被包裹在括号,然后order by它。

例如:

order by (concat(title, description) like '%keyword1%') 
  + (concat(title, description) like '%keyword2%') desc

您可以使用来完成类似的操作fulltext index,但是权重可能有些奇怪。语法如下:

create fulltext index idx on search_table(title, description)

^^只需做一次。

select *
  from search_table
  where match(title, description) against ('keyword1 keyword2 ...')
  order by match(title, description) against ('keyword1 keyword2 ...') desc

这具有极大的好处,那就是构造查询的烦恼要少得多。

这是为您演示两种方法的概念证明。(尽管仅针对单个列-
但却能说明要点)

2021-07-01