2016-09-04 2 views
2

結果の並べ替え/並べ替えに問題があります。 基本的に私は投稿テーブルを持っています、そして、私はpopularity_countをいくつ持っていますか?私は結果に改ページもしています。私はこのLaravel - PopularityCount属性 - オーダーBy

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

ようなものを使用する場合ので それは例えばので、特定のページのみのためにソートされます。 1ページ目は6,5,4,3,2のような人気数の結果があり、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

私はクエリを書く方法がわかりません。 – Sherif

答えて

1

(実装の観点で)高速なソリューションがoderByRaw()を使用することです:あなたposts表が巨大である場合

$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 
"); 

しかし、これは非常に遅くなります。 2つの結合と2つの集計を持つクエリを作成しようとすることもできますが、それはあまり変わらないでしょう。あなたは5行だけを取得したいとは関係ありません。毎回DBのすべてのポストに対して "人気"を計算する必要があります。

パフォーマンスが問題であれば、あなたはあなたのposts表に3の新しい "キャッシュ" 列を作成することができますインデックスを持つ

  • 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、popularity_countをデータベースに追加するのが最善の方法だと私は信じています。最高のパフォーマンスを発揮し、はるかに高速になります。誰かのコメントや投稿のたびに毎回更新するのに時間がかかるはずはありません。将来(どれくらい多くの人々がウェブサイトを使用するかによって)私はおそらくSOLRまたはElasticSearchを使用する必要があります。 ありがとうございました! – crotoan

0

あなたはそれを取得する前にデータを並べ替える必要があります:あなたはpaginate()sortBy()を使用する場合

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

、あなただけの5つの項目のコレクションを並べ替えています。

+0

それは私のデータベースにpopularity_countカラムがないので、orderByを使うことができません。 – crotoan

+0

なぜ 'sortBy()'でそれを使用しますか?そして、あなたはどのように人気を数えますか? –

+0

私はsortByで間違いを犯し、それがちょうど分かっていることに気付きました。私はそれを数える関数PopularCountとgetPopularityCountAttributeを持っています。それはcorectly作品 – crotoan