2016-09-16 2 views
2

Ich habe eine einfache Liste von Gruppen mit Benutzern darin aufgeführt.Eager Load mit Limit für Benutzer pro Gruppe

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

Mit diesem Code bekomme ich alle Daten.

enter image description here

Mein Ziel ist es max Benutzer in dieser Liste auf 10 pro jeder Liste zu begrenzen. Problem ist, wenn ich dem Code hinzufügen -> Limit (10) ... Ich beschränke alle Benutzer in allen Gruppen. Wenn ich also 10 Gruppen habe, werde ich wahrscheinlich 1 Benutzer in jeder Gruppe bekommen.

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

Meine Frage ist, wie kann ich das auf 10 Benutzer pro Gruppe beschränken.

Inzwischen withound -> Grenzwert (10) Ich kann nicht meine Ergebnisse mit diesem Code in foreach bekommen ...

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

Aber es ist nicht perfekt in Bezug auf optymalization, denn ich habe immer alle Benutzer und Show nur 10.

enter image description here

+1

Sie könnten sich für https://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/ interessieren. –

Antwort

0

können Sie haben Offset verwenden oder das überspringen() -Methode:

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

oder

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

In diesem Beispiel Offset/skip ist, wie Anzahl der Zeilen, die Sie überspringen möchten, und dann die nächsten fünf Werte annehmen. In diesem Fall überspringt es die ersten 10 und bringt Ihnen die Daten aus den Zeilen 10-15. Sie müssen den Wert des Offsets jedes Mal an Ihren Controller weitergeben.

Wenn Sie nicht irgendetwas davon tun möchten, können Sie laravels Paginierung verwenden:

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

15 die Anzahl der Daten, die du pro Seite angezeigt werden sollen. Rück dies Ihrer Ansicht nach, und Sie werden es wie folgt angezeigt:

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

{{ $users->links() }} 

Diese für larave 5. * funktioniert, suchen Sie einfach die richtige Dokumentation für die Version Sie verwenden.

Laravel Pagination Doc

Laravel 5.3 Skip Doc

0

In der Tat versucht, 1 Abfrage in der Datenbank zu tun, um den Top-X Datensätze jede Gruppe in einer Gruppe von Aussage zu holen ist eine komplexe Sache zu tun, in der Regel unter Verwendung von Variablen erreicht temporäre Tabellen, spezielle Funktionen, Vereinigungen oder andere Arten von Tricks.

Um dies durch ein Datenmodell des Frameworks zu erreichen, erhöht sich die Komplexität noch mehr.

Ich würde stattdessen vorschlagen, Sie tun, N + 1 Abfragen (wo N würde auf eine maximale Konstante hoffentlich begrenzt werden) wo N ist die Anzahl der Gruppen, die Sie haben.

Also, hier ist was ich meine.

Holen Sie die Liste der Gruppen, und hier stellen Sie sicher, dass Sie die maximale begrenzen, es wäre nicht sinnvoll, eine große Anzahl von Gruppen sowieso zu holen, und auf diese Weise sicherstellen, dass Sie keine schlechte Leistung zu machen viele Abfragen.

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

Dann iterieren Sie über diese Gruppe Liste der Top-X-Benutzer zu holen:

$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 

Und dort gehen Sie.
Normalerweise würden Sie eine ausgefallene Abfrage bevorzugen, die alles auf einmal bringt, aber in diesem Fall würde das wahrscheinlich mit einem wirklich komplexen Code und einer Abfrage enden, die schwer zu verstehen und zu entschlüsseln wäre.
Damit sollte die Leistung in Ordnung sein und Sie erhalten die Ergebnisse in einem kurzen und lesbaren Code.

Ich hoffe es hilft.

aktualisieren

Sie auch die Seite, wenn es viele Gruppen Paginieren kann.
Um dies zu tun, müssen Sie nur die paginate() Funktion in der ersten Abfrage verwenden, die die Gruppen abruft.