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

如何通过Laravel关联Eloquent预加载获取最新5位唯一评论者用户信息

问题根因

你当前使用的distinct('user_id')写法不符合SQL的执行逻辑:

  • SQL里DISTINCT是对查询返回的所有列的组合做去重,你同时查询了id(评论主键,每条唯一)、parent_id等字段,就算加上distinct也不会只按user_id去重,自然达不到预期效果。
  • 如果直接用groupBy('user_id'),在MySQL默认开启ONLY_FULL_GROUP_BY模式的情况下,会因为查询的非聚合字段没有出现在group by里报错,而且默认group by取的是最早的匹配数据,不是最新的评论对应的用户。

最优方案(数据库层面查询,性能最佳)

适配Laravel 8+版本,直接修改Post模型中的commenter_avatars关联方法即可:

public function commenter_avatars()
{
    // 子查询:先取当前帖子下顶级评论中,每个user_id对应的最新一条评论ID
    $latestCommentIds = Comment::selectRaw('MAX(id) as id')
        ->whereColumn('post_id', 'posts.id')
        ->whereNull('parent_id')
        ->groupBy('user_id')
        ->orderBy('id', 'desc')
        ->limit(5);

    // 关联查询完整评论信息,预加载用户数据
    return $this->hasMany(Comment::class)
        ->whereIn('id', $latestCommentIds)
        ->orderBy('id', 'desc')
        ->with('user:id,first_name,last_name,username,avatar');
}

你的控制器代码无需任何修改,原有逻辑即可正常返回预期结果。该方案所有逻辑都在数据库层面完成,即使单帖评论量很大也不会有性能问题。


备用方案(小数据量场景,写法更简洁)

如果单帖评论量长期低于100条,也可以用集合方法处理,代码更易维护:

public function commenter_avatars()
{
    return $this->comments()
        ->whereNull('parent_id')
        ->with('user:id,first_name,last_name,username,avatar')
        ->latest()
        ->get()
        ->unique('user_id')
        ->take(5);
}

注意该方案会先查询所有符合条件的评论再做去重截取,数据量大时性能损耗明显,仅适合小流量场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 02:18:02