制定趋势查询 - Laravel Eloquent
Working out a trending query - Laravel Eloquent
大家好,我正在尝试开发一个查询,其中 returns 来自数据库的热门文章。
热门文章基于过去 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 排序)
感谢帮助
你有几种方法可以采用,
就像@Oli 说的那样,在您的 table 中添加一列,您可以在其中保存最近 24 小时的 number_views,数据库中的触发器将使其保持最新.就像每次有视图时它都会重新计算字段。
添加附加的 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
第三个选项是使用 SQL,它看起来像这里的样子:https://laracasts.com/discuss/channels/general-discussion/eloquent-order-by-related-table
以性能为中心的解决方案应该是:
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 使用原始 select 或使用像@Cptmaxon 建议的集合过滤器,这样速度较慢。
大家好,我正在尝试开发一个查询,其中 returns 来自数据库的热门文章。
热门文章基于过去 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 排序)
感谢帮助
你有几种方法可以采用,
就像@Oli 说的那样,在您的 table 中添加一列,您可以在其中保存最近 24 小时的 number_views,数据库中的触发器将使其保持最新.就像每次有视图时它都会重新计算字段。
添加附加的 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
第三个选项是使用 SQL,它看起来像这里的样子:https://laracasts.com/discuss/channels/general-discussion/eloquent-order-by-related-table
以性能为中心的解决方案应该是:
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 使用原始 select 或使用像@Cptmaxon 建议的集合过滤器,这样速度较慢。