Laravel - Limit each child item efficiently

喜夏-厌秋 提交于 2019-12-17 18:58:47

问题


I have this:

$commentReplies = Comment::whereIn('comment_parent_id', $CommentsIDs)
                                  ->take(2)->get();

Where $CommentsIDs is an array of 3 parent comment ids (1,2,3).

I am trying to retrieve 2 replies for each of the $commentsIDs if they exist. So a total of 6 replies (2 for each comment) should come back with the query, if the replies exist, nothing more. However, with take(2) in there, it limits the replies to 2, and we only get 2 replies for one of the comments. How can it be setup to get 2 replies for each of the comment IDs in the most efficient way, and how can they get rendered in the view with the correct nesting?

Something like:

Comment 1
--Comment 1 Reply 1 (load this)
--Comment 1 Reply 2 (load this)
--Comment 1 Reply 3 (don't load this)
--Comment 1 Reply 4 (don't load this)
Comment 2
--Comment 2 Reply 1 (load this)
--Comment 2 Reply 2 (load this)
--Comment 2 Reply 3 (don't load this)
Comment 3
(no replies, don't load anything)

Update:
Here is the Comment Model:

class Comment extends BaseModel {

 public function latestTwoComments()
 {
     return $this->hasMany('Comment','comment_parent_id')->latest()->nPerGroup('comment_parent_id', 2);
 }

}

Query:

$comments = Comment::with('latestTwoComments')->get();
dd(DB::getQueryLog());

// Result:
'query' => string 'select * from (select `comments`.*, @rank := IF(@group = comment_parent_id, @rank+1, 1) as rank_575b053fb57f8fab5bc86dd324b39b91, @group := comment_parent_id as group_575b053fb57f8fab5bc86dd324b39b91 from (SELECT @rank:=0, @group:=0) as vars, comments where `comments`.`deleted_at` is null order by `comment_parent_id` asc, `created_at` desc) as comments where `comments`.`deleted_at` is null and `rank_575b053fb57f8fab5bc86dd324b39b91` <= ? and `comments`.`comment_parent_id` in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?'... (length=603)

回答1:


You can't use limit/skip when eager loading, for it will limit whole related result.

I suppose you use MySQL, so here is what you need: http://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/

It's way to long to paste here, so just to get the idea: You need MySQL variables to do the job of fetching n per parent for you, like:

public function latestTwoComments()
{
  return $this->hasMany('Comment', 'comment_parent_id')->latest()->nPerGroup('comment_parent_id', 2);
}

//then
$comments = Comment::with('latestTwoComments')->get();
// now all the comments will have at most 2 related child-comments

Note: it's meant for hasMany relation and MySQL



来源:https://stackoverflow.com/questions/26247467/laravel-limit-each-child-item-efficiently

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!