Laravel-эффективно ограничить каждый дочерний элемент

у меня есть это:

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

здесь $CommentsIDs представляет собой массив из 3 родительских идентификаторов комментариев (1,2,3).

Я пытаюсь получить 2 ответа для каждого из $commentsIDs, если они существуют. Таким образом, в общей сложности 6 ответов (2 для каждого комментария) должны вернуться с запросом, если ответы существуют, ничего больше. Однако с take (2) там он ограничивает ответы 2, и мы получаем только 2 ответа на один из комментариев. Как можно настроить получение 2 ответов для каждого идентификатора комментария наиболее эффективным способом, и как они могут получить визуализацию в представлении с правильной вложенностью?

что-то типа:

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)

обновление:
Вот модель комментариев:

class Comment extends BaseModel {

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

}

запрос:

$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 ответов


вы не можете использовать limit/skip когда жаждущая загрузка, ибо она ограничит весь родственный результат.

Я полагаю, вы используете MySQL, так вот что вам нужно: http://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/

это способ долго вставлять здесь, поэтому просто чтобы получить идею: вам нужны переменные MySQL, чтобы выполнить работу по извлечению n на родителя для вас, например:

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

Примечание: он предназначен для hasMany отношения и MySQL