2016-09-04 45 views
2

我在訂購/排序結果時遇到問題。 基本上我有職位表和我計數popular_count根據多少評論和喜歡它有。事情是,我也分頁結果。所以 當我使用這樣的Laravel - PopularityCount屬性 - 訂購者

$Posts->paginate(5); 
$Posts->sortBy('popularity_count'); 
$Posts->get(); 

它排序只對特定的頁面,所以如。第1頁有流行結果計數如:6,5,4,3,2,第二頁有10,7,5,2,1。正如你所看到的那樣,有一些熱門文章,它應該是第一頁的第一個結果。

當我嘗試使用

$Posts->orderBy('popularity_count') 

這是行不通的,因爲我不我的數據庫這樣有列。有沒有可能實現我想要的,而不使用RAW選擇和連接?我的模型上有更多的自定義屬性。

謝謝!

編輯:

`public function getPopularityCountAttribute(){ 

    $comments = $this->getRelation('commentsCount'); 

    $likes = $this->getRelation('likesCount'); 


    $comments = ($comments) ? (int) $comments->comments_count : 0; 

    $likes = ($likes) ? (int) $likes->likes_count : 0; 

    $Result = $likes + ($comments * 1.2); 

    return $Result; 
}` 
+1

嘗試使用DB ::原始的sql查詢...我不知道如何編寫查詢。 – Sherif

回答

1

快速的解決方案(在執行方面)是使用oderByRaw()

$Posts->orderByRaw(" 
    (
     select count(*) 
     from likes 
     where likes.post_id = posts.id 
    ) + (
     select count(*) 
     from comments 
     where comments.post_id = posts.id 
    ) * 1.2 DESC 
"); 

不過,這將是,如果你的posts表是巨大的很慢。你可以嘗試創建一個包含兩個連接和兩個聚合的查詢,但這不會有太大的改變。不要緊,你只需要讀取5行 - 你需要計算每次發佈的每個帖子的「流行度」。

因此,如果性能是一個問題,你可以在你posts表中創建三個新的 「緩存」 列:

  • likes_count
  • comments_count
  • popularity

與索引爲popularity列。

您每次插入或刪除評論或類似內容時,還需要更新相關文章。我可能會用觸發器來做到這一點。

這樣,您就可以使用orderBy('popularity', 'DESC')

您還可以使用列post_id, comments_count, likes_count, popularity創建一個新表(post_popularity),以物理分隔緩存的數據。但後來你需要一個加入:

$Posts->join('post_popularity as pp', 'pp.post.id', '=', 'posts.id') 
     ->orderBy(pp.popularity, 'DESC'); 
+0

嘿。我相信這將是將likes_count,comments_count和popular_count添加到數據庫的最佳方式。它會有最好的表現,而且會更快。每次有人發表評論或發佈帖子時,都不需要太多時間來更新它。在將來(取決於有多少人會使用該網站),我將不得不使用SOLR或ElasticSearch。 謝謝你的幫助! – crotoan

0

你應該得到它之前對數據進行排序:

$Posts->orderBy('popularity_count')->paginate(5); 

當您使用paginate()sortBy(),你只能選5項集合。

+0

就是這樣的,我沒有在我的數據庫中的popular_count列,所以我不能使用orderBy – crotoan

+0

爲什麼你在'sortBy()'中使用它呢?你怎麼算受歡迎? –

+0

我用sortBy犯了一個錯誤,並意識到它只是知道。我有函數PopularityCount和getPopularityCountAttribute來計算它。它正常工作 – crotoan