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

Laravel中如何统计主题下包含回复的总评论数?

方案1:单SQL查询统计(无需修改表结构)

适用场景:查询频率低、不想额外维护冗余字段

如果你的comments表设计中所有评论(含回复)都冗余存储了topic_id字段,直接统计指定主题ID下的所有评论行即可,全程不会加载任何评论模型实例,不会触发自定义属性逻辑:

// 在Topic模型中新增访问器
public function getTotalCommentsAttribute()
{
    return \App\Models\Comment::where('topic_id', $this->id)->count();
}

如果你的回复仅存储parent_id未关联topic_id,可以用递归CTE实现单次查询统计(支持MySQL 8.0+、PostgreSQL等主流数据库):

// 在Topic模型中新增访问器
public function getTotalCommentsAttribute()
{
    return \App\Models\Comment::query()
        ->selectRaw('COUNT(*) as total')
        ->fromRaw(
            'WITH RECURSIVE comment_tree AS (
                SELECT id FROM comments WHERE topic_id = ? AND parent_id IS NULL
                UNION ALL
                SELECT c.id FROM comments c INNER JOIN comment_tree ct ON ct.id = c.parent_id
            ) SELECT * FROM comment_tree',
            [$this->id]
        )
        ->value('total');
}

方案2:冗余字段+事件触发(查询性能最优)

适用场景:查询频率高、对性能要求高

  1. 先给topics表新增整数字段total_comments_count,默认值设为0
  2. 在Comment模型中新增事件监听,评论(含回复)新增/删除时自动更新对应主题的统计值:
// Comment模型的boot方法中新增事件逻辑
protected static function booted()
{
    // 新增评论时计数+1
    static::created(function (\App\Models\Comment $comment) {
        $comment->topic()->increment('total_comments_count');
    });

    // 删除评论时计数-1
    static::deleted(function (\App\Models\Comment $comment) {
        $comment->topic()->decrement('total_comments_count');
    });
}

后续直接调用$topic->total_comments_count即可拿到总数量,无需执行额外查询,性能消耗最低。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:45:01