2016-09-16 8 views
2

У меня есть простой список групп с указанными в нем пользователями.Eager Load with Limit для пользователей на группу

$groups = Group::with(['users' => function ($query) { 
     $query->orderBy('last_login', 'ASC'); 
}])->get(); 

С помощью этого кода я получаю все данные.

enter image description here

Моя цель состоит в том, чтобы ограничить максимального количества пользователей в этом списке до 10 в каждом списке. Проблема заключается в том, когда я добавляю -> предел (10) в код ... Я ограничиваю всех пользователей во всех группах. Поэтому, если у меня есть 10 групп, я буду радовать 1 пользователя в каждой группе.

$groups = Group::with(['users' => function ($query) { 
     $query->orderBy('last_login', 'ASC')->limit(10); 
}])->get(); 

Вопрос: как я могу ограничить это до 10 пользователей в группе.

К настоящему времени withound -> предел (10) Я не могу получить мои результаты с этим кодом в Еогеасп ...

@if ($loop->iteration == 10) 
     @break 
@endif 

Но она не совершенна с точки зрения optymalization, потому что у меня всегда есть все пользователи и шоу только 10.

enter image description here

+1

Возможно, вас заинтересует https://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/ –

ответ

0

Вы можете использовать для смещения или метод пропуска():

$users = DB::table('users') 
       ->offset(10) 
       ->limit(5) 
       ->get(); 

или

$users = DB::table('users')->skip(10)->take(5)->get(); 

В этом примере, офсет/пропуск, как количество строк, которые вы хотите, чтобы пропустить, а затем принять следующие 5 значений. В этом случае он пропустит первые 10 и доставит вам данные из строк 10-15. Вы должны будете каждый раз передавать значение смещения вашему контроллеру.

Если вы не хотите, чтобы делать все это, вы можете использовать laravels пагинации:

$users = User::where('votes', '>', 100)->paginate(15); 

15 является количество данных, которые вы хотите показать на странице. Возвращение это на ваш взгляд, и вы будете показывать это следующим образом:

@foreach ($users as $user) 
    {{ $user->name }} 
@endforeach 

{{ $users->links() }} 

Это работает для larave 5. *, просто искать правильную документацию для версии, которую вы используете.

Laravel Pagination Doc

Laravel 5.3 Skip Doc

0

На самом деле пытается сделать 1 запрос в базе данных, чтобы получать верхние X записи каждой группы в группе по заявлению является сложным, что нужно сделать, как правило, достигается с помощью переменных , временные таблицы, специальные функции, союзы или другие трюки.

Затем, пытаясь добиться этого благодаря привязке модели данных каркаса, она еще больше повышает сложность.

Я бы предложил вам выполнить N + 1 запросов (где N будет ограничено максимальной константой, надеюсь), где N - количество групп, которые у вас есть.

Итак, вот что я имею в виду.

Извлеките список групп, и здесь убедитесь, что вы ограничиваете максимальный размер, было бы бессмысленно получать огромное количество групп в любом случае, и таким образом вы убедитесь, что не получаете плохую производительность для создания много запросов.

$group_list = Group::orderBy('somethingYouLikeHere')->limit(20)->get(); 

Затем перебирать этот список групп, чтобы извлечь из пользователей X:

$all_groups_data = []; 
foreach ($group_list as $group) { 
    $users = User::where('group_id', $group->id)->orderBy('last_login', 'ASC')->limit(10)->get(); 
    $all_groups_data[$group->id] = $users; 
} 
// You could also consider using a collection instead of an array 

И там вы идете.
Обычно вы предпочитаете привлекательный запрос, который сразу выводит все, но в этом случае, вероятно, окажется сложный код и запрос, которые трудно понять и расшифровать.
При этом производительность должна быть хорошей, и вы получите результаты в коротком и читаемом коде.

Надеюсь, это поможет.

Update

Вы можете даже постраничной страницу, если есть много групп.
Для этого вам просто нужно использовать функцию paginate() в первом запросе, который извлекает группы.