2016-04-14 15 views
2

ちょっと私は、データベースからトレンド記事を返すクエリを開発しようとしています。トレンド検索クエリ - Laravel Eloquent

トレンド記事は過去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

記事の閲覧回数を格納している列がありますか。 ( 'number_views'、 'DESC') –

+0

「one-to-many」を指定すると、1つの記事の各ビューに1つの行が表示されているように見えます関係。理想的には、1つのクエリでビューの数をカウントし、後者を実際のアーティクルクエリにインナーで結合する必要があります。 – Mysteryos

+0

はいarticle_id、ipアドレス&created_atを格納するarticle_viewsテーブルがあります – Josh

答えて

5

あなたのことができますいくつかのアプローチを持っています、@Oliよう

  1. が言った、取るあなたが最後の24時間のNUMBER_VIEWSを保存あなたのテーブルに列を追加し、DB内のトリガーは、現在までにそれを維持します。ビューがあるたびにフィールドを再計算します。

  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)ビューアクションの最適化、クエリ操作の速度がはるかに遅い:ビューを追加したときに何もしないで、一時的な列によるビュー数と順序の一時列を追加します。最速の方法は、これは、生の選択を使用するか、または@Cptmaxonが遅くなる示唆したように、コレクションにフィルターを使用してlaravelに変換することができます

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

のようなSQL何かになります。