You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP实现按匹配度排序标签搜索结果,优先展示最优匹配项

实现基于标签匹配度与标签数量差异的搜索结果排序

需求分析

你需要对标签搜索结果进行排序,核心规则是:

  • 优先按匹配到的搜索标签数量降序排列(匹配越多越靠前)
  • 当匹配数量相同时,按结果标签总数与匹配数的差值升序排列(多余标签越少越靠前)

给定的搜索查询、原始结果和期望排序结果如下:
搜索查询:

$search = ['A', 'B'];

原始搜索结果:

$result = [
    [ 'id' => 3011, 'tags' => ['A', 'B', 'C'] ],
    [ 'id' => 10798, 'tags' => ['A','C','D','E'] ],
    [ 'id' => 92, 'tags' => ['A'] ],
    [ 'id' => 4237, 'tags' => ['A', 'B'] ]
];

期望排序结果:

$sortResult = [
    [ 'id' => 4237, 'tags' => ['A', 'B'] ], // 匹配2个标签,差值0,排首位
    [ 'id' => 3011, 'tags' => ['A', 'B', 'C'] ], // 匹配2个标签,差值1,排第二位
    [ 'id' => 92, 'tags' => ['A'] ], // 匹配1个标签,差值1,排第三位
    [ 'id' => 10798, 'tags' => ['A','C','D','E'] ] // 匹配1个标签,差值2,排末位
];

实现方案

我们可以用PHP的usort()函数,自定义比较逻辑来实现这个排序规则:

$search = ['A', 'B'];
$result = [
    [ 'id' => 3011, 'tags' => ['A', 'B', 'C'] ],
    [ 'id' => 10798, 'tags' => ['A','C','D','E'] ],
    [ 'id' => 92, 'tags' => ['A'] ],
    [ 'id' => 4237, 'tags' => ['A', 'B'] ]
];

usort($result, function($a, $b) use ($search) {
    // 计算每个结果匹配的标签数量
    $matchCountA = count(array_intersect($a['tags'], $search));
    $matchCountB = count(array_intersect($b['tags'], $search));
    
    // 优先按匹配数量降序
    if ($matchCountA !== $matchCountB) {
        return $matchCountB - $matchCountA;
    }
    
    // 匹配数量相同时,按多余标签数量升序(差值=总标签数-匹配数)
    $extraCountA = count($a['tags']) - $matchCountA;
    $extraCountB = count($b['tags']) - $matchCountB;
    
    return $extraCountA - $extraCountB;
});

// 输出排序后的结果
print_r($result);

代码解释

  1. 匹配数量计算:使用array_intersect()获取结果标签与搜索标签的交集,交集的长度就是匹配到的标签数量。
  2. 第一优先级排序:如果两个结果的匹配数量不同,直接按匹配数量从高到低排序($matchCountB - $matchCountA实现降序)。
  3. 第二优先级排序:当匹配数量相同时,计算每个结果中多余的标签数量(总标签数减去匹配数),按多余数量从少到多排序($extraCountA - $extraCountB实现升序)。

验证结果

运行上述代码后,输出的结果会和你期望的$sortResult完全一致,满足你的排序需求。

内容的提问来源于stack exchange,提问作者Dieter Information

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:39:07