制定一个趋势查询 - Laravel Eloquent

时间:2016-04-14 04:23:27

标签: sorting laravel eloquent trending

嘿伙计们我正在尝试开发一个从数据库中返回趋势文章的查询。

趋势文章基于过去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排序)

帮助表示赞赏

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

以性能为中心的解决方案应该是:

A)优化查询操作,稍慢查看操作:每次有视图时更新一列,然后通过对该列进行排序查询 - 最佳解决方案是每次添加视图时向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

这可以转换为laravel使用原始选择或使用像@Cptmaxon建议的那样较慢的集合上的过滤器。