2016-09-23 2 views
0

У меня есть таблица с именем comments со следующими столбцами:Ограничить число результатов в гнездовом запросе

| id | user_id | post_id | parent_id | text | 

Я имею эту установку для вложенной системы комментариев, как Disqus:

enter image description here

Если комментарий не имеет родительского комментария, parent_id будет 0. Но если в комментарии есть родитель, то parent_id будет id из p комментарий.

В моей Comments.php модели, у меня есть отношения:

public function children() 
{ 
    return $this->hasMany('App\Comment', 'parent_id', 'id')->with('children'); 
} 

Теперь, если я запрашиваю комментарии:

$comments = Comment::where('post_id', 1) 
    ->where('parent_id', 0) 
    ->with('children') 
    ->get(); 

Результат будет выглядеть примерно так:

[ 
    { 
     "id": 5, 
     "user_id": "2", 
     "post_id": "1", 
     "parent_id": "0", 
     "text": "Text", 
     "children": [ 
      { 
       "id": 7, 
       "user_id": "1", 
       "post_id": "1", 
       "parent_id": "5", 
       "text": "Text", 
       "children": [ 
        { 
         "id": 8, 
         "user_id": "3", 
         "post_id": "1", 
         "parent_id": "7", 
         "text": "Text", 
         "children": [ 

         ] 
        }, 
        { 
         "id": 11, 
         "user_id": "3", 
         "post_id": "1", 
         "parent_id": "7", 
         "text": "Text", 
         "children": [ 

         ] 
        }, 
       ] 
      }, 
      { 
       "id": 9, 
       "user_id": "1", 
       "post_id": "1", 
       "parent_id": "5", 
       "text": "Text", 
       "children": [ 

       ] 
      } 
      , 
      { 
       "id": 10, 
       "user_id": "1", 
       "post_id": "1", 
       "parent_id": "5", 
       "text": "Text", 
       "children": [ 

       ] 
      } 
     ] 
    }, 
    { 
     "id": 6, 
     "user_id": "3", 
     "post_id": "1", 
     "parent_id": "0", 
     "text": "Text", 
     "children": [ 

     ] 
    } 
] 

Или, проще говоря:

- 5 
-- 7 
--- 8 
--- 11 
-- 9 
-- 10 
- 6 

Что я хочу сделать, это ограничить количество результатов, возвращаемых на глубину.

Так, к примеру, как я могу изменить мой запрос/код таким образом, что он возвращает:

  • Десять результатов верхнего уровня (parent_id 0)
  • Два уровня 1 результатов
  • One уровень-2 результат

Таким образом, в конце концов, запрос должен выводить комментарии, как это:

- 5 
-- 7 
--- 8 
-- 9 
- 6 

Как вы можете видеть, есть два результата верхнего уровня (до 10 разрешенных), два результата уровня 1 и один результат уровня 2.

Как это сделать?

+0

сделал вы пытаетесь ['limit()'] (https://laravel.com/docs/5.3/queries#ordering-grouping-limit-and-offset)? –

ответ

1

Вместо использования with в модели, которая может привести к неконтролируемому извлечению данных, почему бы не сделать это, когда вам это нужно?

Это значит, в вашем Comment.php, удалите with:

public function children() 
{ 
    return $this->hasMany('App\Comment', 'parent_id', 'id'); 
} 

И в классах контроллер/хелперов/услуг, только вернуть то, что вам нужно?Например:

$comments = Comment::where('post_id', 1) 
    ->where('parent_id', 0) 
    ->with('children' => function($query) { 
     $query->with('children' => function($query) { 
      $query->with('children') 
        ->orderBy('created_at', 'desc') 
        ->take(1); //last 1 
     }) 
     ->orderBy('created_at', 'desc') 
     ->take(2); // intermediate 2 
    }) 
    ->orderBy('created_at', 'desc') 
    ->take(10) //the outermost 10 
    ->get(); 

еще не проверял, но теоретически должно работать :)

Примечание: Добавлен заказ по created_at, потому что мы обычно хотим последние несколько комментариев к выходит в верхней :)

+0

Использование 'limit' или' take', когда интенсивная загрузка не делает то, что вы думаете. Когда вы произносите 'take (2)' в нетерпеливой нагрузке, он не только загрузит 2 детей для каждого внешнего комментария, он будет только загружать 2 ребенка. Таким образом, у одной родительской платы есть 2 ребенка, но ни у кого из родителей нет детей. Или, у двух родителей будет по 1 ребенка, но ни у кого из родителей нет детей. – patricus