Laravel中如何基于模型关联正确使用orderBy方法
问题根因
Post::orderBy('comments_count')->get()运行失败的原因很简单:posts表默认不存在comments_count字段,Eloquent不会自动统计关联模型的数量,直接查询不存在的字段必然触发SQL错误。
可行实现方案
方案1:调用withCount方法(日常开发首选)
Eloquent原生提供withCount()方法,会自动为目标关联生成计数属性,命名规则为{关联方法名}_count,直接对这个生成的属性排序即可:
// 前提:Post模型中关联Comment的方法名为comments $posts = Post::withCount('comments') ->orderBy('comments_count', 'desc') // 传asc为按评论数升序排列 ->get();
查询结果中每个Post实例可以直接通过$post->comments_count读取对应评论总数,代码简洁,ORM底层做了查询优化,常规数据量下性能足够。
方案2:手动联表聚合统计(适合多关联复杂筛选场景)
如果查询需要叠加其他关联表的筛选逻辑,可以手动写左连接统计评论数:
$posts = Post::leftJoin('comments', 'posts.id', '=', 'comments.post_id') ->selectRaw('posts.*, COUNT(comments.id) as comments_count') ->groupBy('posts.id') ->orderBy('comments_count', 'desc') ->get();
注意必须使用
leftJoin,否则没有任何评论的Post记录会被过滤掉。
方案3:新增物理字段+自动计数维护(大数据量场景性能最优)
如果站点内容数据量大,每次查询实时count会带来明显性能损耗,可以在posts表新增物理字段存储评论数,配合Eloquent的自动计数功能维护字段值:
- 首先给posts表新增字段:
// 迁移文件代码 Schema::table('posts', function (Blueprint $table) { $table->unsignedInteger('comments_count')->default(0); });
- 在Comment模型的post关联上开启自动计数:
// Comment模型内的关联定义 public function post() { return $this->belongsTo(Post::class)->withCount('comments'); }
配置完成后,每次新增、删除评论时,Laravel会自动更新对应Post的comments_count字段值,此时你最初写的Post::orderBy('comments_count')->get()可以直接正常运行,不需要额外统计逻辑,查询性能最高。
内容的提问来源于stack exchange,提问作者Paramesh Mishra
相关产品推荐
相关产品推荐

