如何在Laravel中用查询构建器实现嵌套评论层级加载
问题描述
我有一个comments表,包含id、body和parent_id字段,评论支持嵌套子评论,通过parent_id字段关联。需要查询出如下嵌套结构的结果:
[ { "id": 1, "body": "test", "parent_id": null, "comments": [ { "id": 2, "body": "test", "parent_id": 1, "comments": [ { "id": 3, "body": "test", "parent_id": 2 }, { "id": 4, "body": "test", "parent_id": 2 } ] }, { "id": 5, "body": "test", "parent_id": 1, "comments": [] } ] }, { "id": 6, "body": "test", "parent_id": null, "comments": [] } ]
要求不能使用Eloquent预加载(with()),仅通过查询构建器实现。
解决方案
可以通过"单次查询+内存递归组装"的方式实现,具体代码如下:
// 1. 使用查询构建器获取所有评论数据 $allComments = DB::table('comments') ->select('id', 'body', 'parent_id') ->get(); // 2. 递归生成嵌套评论结构 function nestComments($comments, $parentId = null) { $result = []; foreach ($comments as $comment) { if ($comment->parent_id === $parentId) { // 递归查找当前评论的子评论 $comment->comments = nestComments($comments, $comment->id); $result[] = $comment; } } return $result; } // 3. 生成最终嵌套结构 $nestedComments = nestComments($allComments); // 可选:返回JSON格式结果 return response()->json($nestedComments);
关键说明
- 仅执行一次数据库查询,避免了N+1查询问题
- 通过递归函数在内存中完成评论的嵌套组装,完全基于查询构建器获取的数据,未使用Eloquent预加载
- 递归逻辑会自动处理任意层级的子评论,即使评论嵌套深度不确定也能正常工作
内容的提问来源于stack exchange,提问作者DeveloperX
相关产品推荐
相关产品推荐

