return 关系总和聚合的最佳方法 属性
Best way to return the sum aggregation of a relations property
我有一个简单的结构,其中 post 有很多选票。投票的 "value" 属性 为 1 或 -1
在阅读所有 post 时,我希望将每个 post 的总和 select 转化为 post 级别的自定义 属性。目前我这样做
$posts = Post::where('published_at', '<=', $date)
->orderBy('published_at', 'desc')
->simplePaginate(20);
$posts->each(function($post) {
$post->overallRating = $post->getRating();
});
这是完全有效的,但我认为对数据库进行 20 次查询以读取评级并不是很好。有没有办法在 posts 的实际获取中简化这一点?
public function getRating()
{
return $this->votes->sum('value');
}
试试这个:
$posts = Post::where('published_at', '<=', $date)
->orderBy('published_at', 'desc')
->with(['votes' => function($query) {
$query->sum('value');
}])->simplePaginate(20);
如果您想保留包含在分页结果中的选票,那么我建议添加 with('votes')
,这样它们至少可以提前加载,即
$posts = Post::with('votes')
->where('published_at', '<=', $date)
->orderBy('published_at', 'desc')
->simplePaginate(20);
但是,如果您 want/aren 不在意获得选票,而只想获得每个 post 的评分,则可以将以下范围添加到 Post
型号:
public function scopeWithRating(Builder $query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$query->selectSub(
$this->votes()->getRelationExistenceQuery(
$this->votes()->getRelated()->newQuery(), $query, new Expression('sum(value)')
)->toBase(),
'rating'
);
}
然后:
$posts = Post::withRating()
->where('published_at', '<=', $date)
->orderBy('published_at', 'desc')
->simplePaginate(20);
希望对您有所帮助!
我有一个简单的结构,其中 post 有很多选票。投票的 "value" 属性 为 1 或 -1
在阅读所有 post 时,我希望将每个 post 的总和 select 转化为 post 级别的自定义 属性。目前我这样做
$posts = Post::where('published_at', '<=', $date)
->orderBy('published_at', 'desc')
->simplePaginate(20);
$posts->each(function($post) {
$post->overallRating = $post->getRating();
});
这是完全有效的,但我认为对数据库进行 20 次查询以读取评级并不是很好。有没有办法在 posts 的实际获取中简化这一点?
public function getRating()
{
return $this->votes->sum('value');
}
试试这个:
$posts = Post::where('published_at', '<=', $date)
->orderBy('published_at', 'desc')
->with(['votes' => function($query) {
$query->sum('value');
}])->simplePaginate(20);
如果您想保留包含在分页结果中的选票,那么我建议添加 with('votes')
,这样它们至少可以提前加载,即
$posts = Post::with('votes')
->where('published_at', '<=', $date)
->orderBy('published_at', 'desc')
->simplePaginate(20);
但是,如果您 want/aren 不在意获得选票,而只想获得每个 post 的评分,则可以将以下范围添加到 Post
型号:
public function scopeWithRating(Builder $query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$query->selectSub(
$this->votes()->getRelationExistenceQuery(
$this->votes()->getRelated()->newQuery(), $query, new Expression('sum(value)')
)->toBase(),
'rating'
);
}
然后:
$posts = Post::withRating()
->where('published_at', '<=', $date)
->orderBy('published_at', 'desc')
->simplePaginate(20);
希望对您有所帮助!