2016-04-14 50 views
2

嘿傢伙我試圖開發一個查詢,從數據庫返回熱門的文章。制定一個趨勢查詢 - Laravel雄辯

熱門文章基於過去24小時內的最多瀏覽量。這是迄今爲止代碼:

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

return $trending; 
} 

文章模型有如下關係:

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

查詢作品,但不知何故,我需要通過觀看計數的文章也進行排序。例如,顯示目前趨勢的文章,但與大多數觀點計數artticles不是從一階到最後(顯然 - 他們是由created_at訂購)

幫助表示讚賞

+0

您是否有任何colomns存儲文章的視圖數量。如果你有,那麼你也可以將它包括在查詢中,再次使用orderBy('number_views','DESC') –

+0

看起來他對於一篇文章中的每個視圖都有一行,因爲'one-to-many'關係。理想情況下,他應該對一個查詢中的視圖進行計數,並將後者與實際的文章查詢結合起來。 – Mysteryos

+0

是的,我有一個article_views表,它存儲article_id,IP地址和created_at – Josh

回答

5

你有幾種方法,你可以走,

  1. 像@Oli說,一列添加到您的表,其中保存最後24小時NUMBER_VIEWS,一個數據庫中的觸發器將保持最新狀態。就像每次看到它都會重新計算字段。

  2. 添加一個附加24h_views_count運行查詢,然後排序的代碼

    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. 第三個選擇是使用SQL和它看起來像它看起來在這裏:https://laracasts.com/discuss/channels/general-discussion/eloquent-order-by-related-table

2

以性能爲中心的解決方案應該是:

A)優化查詢操作,稍慢查看操作:更新列e非常時間有一個視圖,然後通過排序查詢列 - 最好的解決方案是添加一個觸發器到MySQL每次添加視圖來更新文章中的查看列。

B)優化視圖動作,慢得多的查詢動作:添加視圖時不要做任何事情,添加一個臨時列,這是一個視圖計數的臨時列,並通過此臨時列進行排序。最快的方式將與SQL類似

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

這可以被翻譯使用原料選擇或使用收集過濾器像@Cptmaxon建議是慢laravel。