Laravel:嵌套查询连接导致子数组
Posted
技术标签:
【中文标题】Laravel:嵌套查询连接导致子数组【英文标题】:Laravel: Nesting query join results in a sub array 【发布时间】:2017-05-31 02:59:03 【问题描述】:注意请不要建议使用 Eloquent,这是专门针对 Laravel 查询构建器的。
出于性能原因,我们使用查询生成器从表中检索结果:
DB::table('posts')->get();
如果我们想在那个查询上加入一个关系:
DB:table('posts')
->leftJoin('comments', 'posts.id', '=', 'comments.post_id')
->get();
将结果合并到每个帖子的数组中:
[
'id' => 1,
'title' => 'My Blog Post',
'content' => '<h1>This is a post</h1><p>hello world</p>',
'post_author' => 'Billy',
'comment' => 'This is a comment',
'comment_author' => 'Andrew',
]
我们如何将连接的结果放入嵌套数组中?如:
[
'id' => 1,
'title' => 'My Blog Post',
'content' => '<h1>This is a post</h1><p>hello world</p>',
'post_author' => 'Billy',
'comment' => [
'id' => 22,
'comment' => 'This is a comment',
'comment_author' => 'Andrew',
],
]
【问题讨论】:
尝试定义适当的关系。 关系仅用于 Eloquent 的情况。 Laravel 查询生成器不处理关系。 @SougataBose 查询返回的格式有什么问题? 我知道。如果你们有关系,那么这很容易做到。 @SougataBose 问题明确指出不要使用 Eloquent ...... 【参考方案1】:不要认为没有 Eloquent 就可以开箱即用。
你可以走原始路线:
$results = DB:table('posts')
->leftJoin('comments', 'posts.id', '=', 'comments.post_id')
->select('posts.*', 'comments.*', 'comments.id as comments_id')
->get();
foreach($results as &$result)
$result['comment'] = [
'id' => $result['comment_id'],
'comment' => $result['comment'],
'comment_author' => $result['comment_author']
];
unset($result['comment_author'], $result['comment_id']);
【讨论】:
我希望 eloquent 有一种更微妙的方式来处理结果,至少作为一种选择。 您的解决方案没有将每个帖子的所有 cmets 分组为一个嵌套数组,实际上每个帖子会出现 N 次,当 N 是它的 cmets 数时。 这会使查询变得非常慢,好像有超过 10000+ 个帖子,然后查询本身将需要几秒钟才能执行【参考方案2】:由于你使用的是 DB 外观而不是 Eloquent,并且不能使用内置的 with()
方法,你必须自己实现它:
$posts = DB::table('posts')->get()->toArray();
$comments = DB::table('comments')->get()->toArray();
foreach($posts as &$post)
$post->comments = array_filter($comments, function($comment) use ($post)
return $comment->post_id === $post->id;
);
return $posts;
如果你想摆脱 post_id
的 cmets 条目,你可以这样做:
$posts = DB::table('posts')->get()->toArray();
$comments = DB::table('comments')->get()->toArray();
foreach($posts as &$post)
$comments = array_filter($comments, function($comment) use ($post)
return $comment->post_id === $post->id;
);
$post->comments = array_map(function ($comment)
unset($comment->id);
return $comment;
, $comments);
return $posts;
(我猜运行时会类似于with()
,因为毕竟mysql 不提供开箱即用的功能)。
【讨论】:
以上是关于Laravel:嵌套查询连接导致子数组的主要内容,如果未能解决你的问题,请参考以下文章