如何在具有关系总和的Laravel模型上使用紧急加载-当前获得多个查询(N + 1) [英] How to use eager loading on Laravel model with SUM of a relationship - currently getting multiple queries (N+1)

查看:49
本文介绍了如何在具有关系总和的Laravel模型上使用紧急加载-当前获得多个查询(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆