繁体   English   中英

如何使用 Eloquent 在 Laravel 中预先加载聚合?

[英]How to eager load Aggregates in Laravel with Eloquent?

在我的应用程序中,我有一长串类别。 我用这个加载它们:

$categories = Categories::all();

Categories有这个功能:

public function transactions()
{
    return $this->hasMany(Transactions::class);
}

public function getPreviousActivityAttribute() {
    return $this->transactions()
        ->where('date', '<' Carbon::now()->firstOfMonth())
        ->sum('amount');
}

我将此类别列表呈现为表格。 每一行都在调用$category->previousActivity

这导致 n+1 数据库查询,其中 n 是类别的数量(及其很多)。 除了previousActiviy我还显示其他聚合(有些做SUM其他做AVG等)。

顺便一提。 有很多交易。 我无法使用Categories::with('transactions')->get()加载它们。 这将需要太多内存。

有没有办法急切加载聚合? 查询构建器上有一个withCount方法,但它在这里并没有真正的帮助。

感谢您的帮助。

一个干净的解决方案是使用withCount如下:

在 Categories.php 中:

public function withPreviousActivity()
    {
        return $this->withCount([
            'transactions as previous_activity' => function ($query) {
                $query->select(DB::raw("SUM(IFNULL(amount,0)) as transactions_count"))->where('date', '<', Carbon::now()->firstOfMonth());
            },
        ]);
    }

别的地方:

dump(Categories::withPreviousActivity()->get()->toArray());

像这样将一个函数附加到模型的构造函数中的withCount属性,以始终预先加载此计数。

public function __construct(array $attributes = array())
{
    parent::__construct($attributes);

    $this->withCount['transactions as total'] = function ($query) {
        $query->select(DB::raw(
            'SUM(IFNULL(amount, 0)) as relationsum'
        ));
    };
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM