Laravel多对多关联查询优化:最少查询获取指定文章所属分类下的全部文章
优化方案
方案1:2次查询,符合Laravel Eloquent规范(推荐绝大多数场景使用)
语义清晰,维护成本低,完全利用Laravel关联特性,不需要手动操作中间表。
首先先修正关联命名(原命名不符合Laravel规范,多对多关联返回多个结果建议用复数小驼峰):
在Post.php中修改关联定义:
public function categories() // 把原来的Category修改为categories { return $this->belongsToMany(Category::class); }
查询代码:
// 仅执行2次SQL查询:1次查目标文章,1次查文章关联的分类 + 所有分类下的关联文章 $post = Post::with('categories.posts')->find(1); // 提取所有分类下的文章,去重,可按需添加排除原文章的逻辑 $relatedPosts = $post->categories->pluck('posts')->flatten()->unique('id'); // 若需要排除原文章本身,追加过滤即可 $relatedPosts = $relatedPosts->where('id', '!=', 1);
方案2:1次查询,极致性能(适合大数据量场景)
通过嵌套whereHas关联查询,仅执行1次SQL即可拿到结果:
$targetPostId = 1; $relatedPosts = Post::whereHas('categories', function ($query) use ($targetPostId) { $query->whereHas('posts', function ($q) use ($targetPostId) { $q->where('posts.id', $targetPostId); }); }) // 可选:排除原文章本身 ->where('id', '!=', $targetPostId) ->get();
额外说明
两种方案都远优于原有4次查询的实现,且完全符合Laravel的编码规范,不需要手动拼接中间表查询逻辑,后续表结构变更时维护成本更低。
内容的提问来源于stack exchange,提问作者Kathir
相关产品推荐
相关产品推荐

