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

Laravel Eloquent按特殊条件排序:分类搜索时优先展示匹配对应话题的新闻

Laravel Eloquent按特殊条件排序:分类搜索时优先展示匹配对应话题的新闻

嘿,我来帮你搞定这个排序需求!你的核心诉求是:搜索某个分类时,先把话题正好和搜索分类同名的新闻排在最前面,剩下的同分类新闻再跟在后面对吧?

其实实现起来很简单,我们只需要给符合话题匹配条件的新闻加一个「优先级标记」,然后按照这个标记排序就行。下面给你两种靠谱的实现方式:

方法一:用子查询实现排序(推荐,避免表连接的重复问题)

这种方式不需要额外的表连接,直接通过子查询判断当前新闻的话题是否匹配搜索词,然后按这个结果排序:

$search = 'TV series';

$query = News::with(['category_related', 'topic_related'])
    // 先筛选出包含目标分类的新闻
    ->whereHas('category_related', function($q) use ($search) {
        $q->where('name', 'like', "%{$search}%");
    })
    // 核心排序逻辑:如果新闻的话题等于搜索词,优先级为1,否则为0,按优先级倒序
    ->orderByRaw("(
        SELECT COUNT(*) 
        FROM related_post_topic rpt 
        JOIN topics t ON rpt.topic_id = t.id 
        WHERE rpt.post_id = news.id AND t.name = ?
    ) DESC", [$search])
    // 可选:优先级相同的新闻,可以按id倒序(对应你想要的News4→News3的顺序)
    ->orderBy('id', 'desc')
    ->paginate(20);

方法二:用表连接+临时字段排序

这种方式通过连接话题关联表和话题表,创建一个临时的优先级字段,再按这个字段排序:

$search = 'TV series';

$query = News::with(['category_related', 'topic_related'])
    ->whereHas('category_related', function($q) use ($search) {
        $q->where('name', 'like', "%{$search}%");
    })
    // 连接话题关联表和话题表,创建临时字段标记是否匹配
    ->selectRaw('news.*, CASE WHEN topics.name = ? THEN 1 ELSE 0 END AS is_matching_topic', [$search])
    ->join('related_post_topic', 'news.id', '=', 'related_post_topic.post_id')
    ->join('topics', 'related_post_topic.topic_id', '=', 'topics.id')
    // 先按优先级倒序,再按id倒序
    ->orderBy('is_matching_topic', 'desc')
    ->orderBy('news.id', 'desc')
    // 去重,避免因多分类导致的重复记录
    ->distinct()
    ->paginate(20);

为什么这样能解决你的问题?

拿你的例子来说:

  • News4和News3的话题都是「TV series」,优先级标记为1,会排在前面;
  • News5的话题是「crime」,优先级标记为0,会排在最后;
  • 再加上orderBy('id', 'desc'),News4(id4)就会在News3(id3)前面,正好符合你想要的顺序:News4 → News3 → News5。

注意哦:如果你的表名(比如related_post_topic、topics)和实际项目里不一样,记得改成你自己的表名~

备注:内容来源于stack exchange,提问作者Danilo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 11:23:09