如何使用急切加载来查询尽可能少的数据?

Posted

技术标签:

【中文标题】如何使用急切加载来查询尽可能少的数据?【英文标题】:How to use eager loading to query as less data as possible? 【发布时间】:2018-11-19 01:43:36 【问题描述】:

我正在使用 Eloquent ORM,我想设置一个预先加载以查询尽可能少的数据。

我有三个表 countriesstatescities,我想获取某个国家/地区的所有州和城市,而不需要有关该国家/地区的其他信息。

我的模型:

国家

public function states () 
    return $this->hasMany(State::class);

状态

public function country () 
    return $this->belongsTo(Country::class);


public function cities () 
    return $this->hasMany(City::class);

城市

public function state () 
    return $this->belongsTo(State::class);

例如,获取美国的所有州和城市。我想得到如下数据。

[
    
        id: 1,
        name: 'California',
        cities: [
            
                id: 1,
                name: 'Los Angeles'
            
        ]
    
]

我怎样才能只使用 Eloquent ORM 助手而不使用 where 或原始 SQL 来实现这一点?

【问题讨论】:

您是否已经定义了模型及其关系?您可以将它们添加到问题中吗? 我刚刚编辑过。检查一下! 您能否就答案提供反馈? @jonas-staudenmeir 我一直在等待使用 Eloquent Relations (Illuminate\Database\Eloquent\Relations) 的答案。我不认为我得到的答案是令人满意的。也许我需要编辑我的问题... 你是什么意思?两个答案都使用 Eloquent 关系。 【参考方案1】:

你可以这样:

$data = Country::with([
        'states' => function ($query) 
            $query->with([
                'cities'
            ]);
        
    ])->get(['id']);

这更具可读性,不需要原始查询

【讨论】:

【参考方案2】:

您可以像这样限制列:

 Country::with('states:id,name,country_id', 'states.cities:id,name,state_id')->get(['id']);

您必须选择外键列,因为它们是匹配结果所必需的。

您也可以将其集成到states 关系中:

public function states () 
    return $this->hasMany(State::class)->select('id', 'name', 'country_id')
        ->with('cities:id,name,state_id');

当您访问/加载states时,这将自动加载cities

【讨论】:

指定外键是不必要的,至少在官方 Laravel 文档中是这样解释的 -> ` 使用此功能时(渴望加载特定列),您应该始终在您希望检索的列。` lara docs->laravel.com/docs/5.6/eloquent-relationships#eager-loading 这是必要的。在文档示例中,id 是外键。在这种情况下,states.idcountry_idstate_id 是必需的外键。 在文档示例中id 是作者表的主键而不是外键:/ 文档中的这句话措辞不好,它仅指BelongsTo关系。在这种情况下,我们有两个HasMany 关系。在没有country_idstate_id 的情况下尝试我的答案,它不会起作用。 我扩展了我的答案。

以上是关于如何使用急切加载来查询尽可能少的数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 laravel 中检索用户时急切加载?

使用 Rails 查询急切加载

急切加载与加入获取相同吗?

WCF 数据服务和 EF4 CTP5,如何为查询配置默认的急切加载模式?

使用 Laravel 将两个模型合并到一个分页查询中,并带有急切加载的关系

如何急切加载具有条件和当前用户的关联表?