2016-04-14 18 views
2

Hey Leute, ich versuche, eine Abfrage zu entwickeln, die die Trendartikel aus der Datenbank zurückgibt.Ausarbeiten einer Trend-Abfrage - Laravel Eloquent

Die Trendartikel basieren auf den meisten Ansichten der letzten 24 Stunden. Hier ist der Code so weit:

$trending = Article::whereHas('view', function ($query) { 
    $query->where('created_at', '>=', Carbon::now()->subHours(24)); 
}) 
->with('view') 
->orderBy('created_at', 'DESC') 
->get(); 

return $trending; 
} 

Der Artikel Modell hat die folgende Beziehung:

public function view() 
{ 
    return $this->hasMany('ArticleView', 'article_id'); 
} 

Die Abfrage funktioniert, aber ich brauche irgendwie auch die Artikel der Ansicht Zahl zu sortieren. Zum Beispiel werden die zur Zeit Trending Artikel angezeigt, aber die artticles mit der meisten Ansicht Zählung nicht von Anfang bis Ende bestellt (natürlich - sie werden von created_at bestellt werden)

Hilfe

geschätzt
+0

Haben Sie irgendwelche Spalten, wo Sie die Anzahl der Ansichten für den Artikel speichern. Wenn Sie dann haben, können Sie es auch in die Abfrage aufnehmen, verwenden Sie wieder orderBy ('number_views', 'DESC') –

+0

Es scheint, er hat eine Zeile für jede Sicht auf einen Artikel, angesichts der 'one-to-many' Beziehung. Im Idealfall sollte er auf die Ansichten in einer Abfrage zählen und innerlich mit der tatsächlichen Artikelabfrage verbinden. – Mysteryos

+0

Ja, ich habe eine article_views-Tabelle, die die article_id, IP-Adresse und created_at speichert – Josh

Antwort

5

Sie verschiedene Ansätze möglich nehmen,

  1. wie @Oli sagte, eine Spalte zu Ihrer Tabelle hinzuzufügen, wo Sie die NUMBER_VIEWS der letzten 24 Stunden speichern, ein Trigger in der DB wird es stets auf dem neuesten Stand zu bringen. Wie jedes Mal, wenn es eine Ansicht gibt, wird das Feld neu berechnet.

  2. fügt ein hängten 24h_views_count Ihre Abfrage ausführen und dann sortiert in Code

    protected $appends= ['24h_views_count'] 
    
    public get24hViewsCountAttribute(){ 
    return $this->view()->where('created_at', '>=', Carbon::now()->subHours(24))->count(); 
    } 
    
    //and after you get the result from trending just sort the collection via that property. 
    $trending->sortByDesc('24h_views_count');//this will sort it from highest to lowest 
    
  3. die dritte Option ist SQL zu verwenden, und es wird so aussehen, wie es hier aussieht: https://laracasts.com/discuss/channels/general-discussion/eloquent-order-by-related-table

2

Eine leistungsorientierte Lösung sollte entweder:

A) Optimieren Sie Abfrageaktion, etwas langsamer Aktion anzeigen: Aktualisieren Sie eine Spalte e sehr viel Zeit gibt es eine Ansicht und dann abfragen, indem Sie diese Spalte bestellen - beste Lösung ist das Hinzufügen von Trigger zu mysql jedes Mal, wenn eine Ansicht hinzugefügt wird, um die angezeigte Spalte im Artikel zu aktualisieren.

B) Optimieren der Ansicht Aktion, viel langsamere Abfrageaktion: Beim Hinzufügen von Ansichten nichts tun, eine temporäre Spalte hinzufügen, die die Anzahl der Ansichten und die Reihenfolge dieser temporären Spalte angibt. Der schnellste Weg wäre wie

mit SQL etwas sein
select article_name, (select count(*) from views where view.article_id = articles.article_id) as view_count from articles order by view_count 

Dies übersetzt werden kann mit einem rohen wählen oder mit Hilfe eines Filters auf die Sammlung Laravel wie @Cptmaxon vorgeschlagen, die langsamer ist.