如何在具有关系总和的Laravel模型上使用紧急加载-当前获得多个查询(N + 1) [英] How to use eager loading on Laravel model with SUM of a relationship - currently getting multiple queries (N+1)
问题描述
在我的模型中,我附加了一个关系的SUM计算,该关系导致对projectHours属性运行80个查询.
In my model I am appending a SUM calculation of a relationship which causes 80 queries to be run for the projectHours attributes.
如果我不追加projectHours,我将得到6个查询.
If I don't append projectHours I get 6 queries.
我认为这是关系模型中的N + 1个问题.
I believe this is N+1 issue within the model for a relationship.
在模型中是否有某种方法可以使用紧急加载来减少查询?
Is there some way to use eager loading within the model to reduce my queries?
还是应该以不同的方式去做?建议我将其重构为资源,并将紧急负载查询包装在作用域中,以便可以在控制器中执行此操作,但是我认为资源更多用于API端点.
Or should I be going about this a different way? I was suggested to refactor this into a Resource and wrapping the eager-load query in a scope so you could do this in your controller, but I thought resources were more for API endpoints.
感谢帮助.
class Project extends Model
{
protected $appends = ['projectHours'];
public function jobs()
{
return $this->hasMany('App\JobItem', 'project_id', 'id');
}
public function getProjectHoursAttribute()
{
return $this->jobs()->sum('hours');
}
}
推荐答案
因此,您的(N + 1)来自此处:
So your (N + 1) is coming from right here:
$this->jobs()->sum('hours');
它是由您的 jobs
关系作为查询生成器实例 jobs()
It is caused accessing by your jobs
relationship as a query builder instance jobs()
如果要预加载关系然后求和,则可以执行以下操作:
If you want to preload the relationship and then sum the results, you can do it like this:
$this->jobs->sum('hours');
然后使用Eloquent Collection sum
方法
This then uses the Eloquent Collection sum
method
示例
$project = Project::with('jobs')->find(1);
$hours = $project->projectHours;
这篇关于如何在具有关系总和的Laravel模型上使用紧急加载-当前获得多个查询(N + 1)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!