2

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

热门文章基于过去 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');
}

查询有效,但我不知何故还需要按查看次数对文章进行排序。例如,显示当前热门文章,但查看次数最多的文章没有从头到尾排序(显然 - 它们是按 created_at 排序的)

帮助表示赞赏

4

2 回答 2

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

于 2016-04-14T06:41:58.757 回答
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

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

于 2016-04-14T11:04:25.097 回答