英文:
Laravel eloquent query with collection optimization
问题
以下是您控制器中用于显示关于已支付和未支付订单以及相应金额(总额)按年份统计数据的查询。然而,我感到使用的查询可能需要优化,但我无法找到更好的方法来做到这一点。以下是我所拥有的:
public function index(Order $order)
{
$orders = Order::all()->groupBy(function ($order) {
return $order->created_at->format('Y');
})->map(function ($year) {
return $year->sum('total');
});
$unpaid_orders = Order::all()->where('payment_confirmed', 0)->groupBy(function ($order) {
return $order->created_at->format('Y');
})->map(function ($year) {
return $year->sum('total');
});
$paid_orders = Order::all()->where('payment_confirmed', 1)->groupBy(function ($order) {
return $order->payment_confirmed == false ? $order->year : $order->created_at->format('Y');
})->map(function ($year) {
return $year->sum('total');
});
return view('orders.index', compact('orders', 'unpaid_orders', 'paid_orders'));
}
上面的代码中,我三次查询了Order模型,似乎可以进行优化。
英文:
I have the following queries in my controller to show some statistics about orders paid, and unpaid and the respective amounts (totals), by year. Yet, I feel that the queries I'm using may be optimized but I can't figure out a better way to do it. Here's what I have:
public function index(Order $order)
{
$orders = Order::all()->groupBy(function ($order) {
return $order->created_at->format('Y');
})->map(function ($year) {
return $year->sum('total');
});
$unpaid_orders = Order::all()->where('payment_confirmed', 0)->groupBy(function ($order) {
return $order->created_at->format('Y');
})->map(function ($year) {
return $year->sum('total');
});
$paid_orders = Order::all()->where('payment_confirmed', 1)->groupBy(function ($order) {
return $order->payment_confirmed == false ? $order->year : $order->created_at->format('Y');
})->map(function ($year) {
return $year->sum('total');
});
return view('orders.index', compact('orders', 'unpaid_orders', 'paid_orders'));
}
Above I'm querying the Order model three times which it seems that could be optimized.
答案1
得分: 2
Sure, here is the translated code:
一次执行`$collection = Order::all();`,然后在需要时使用`$collection`。
public function index(Order $order)
{
$collection = Order::all();
// 或者
$collection = Order::select(['id', 'payment_confirmed', 'total', 'year', 'created_at'])->get();
$orders = $collection->groupBy(fn ($order) => $order->created_at->format('Y'))
->map(fn ($order) => $order->sum('total'));
$unpaid_orders = $collection->where('payment_confirmed', 0)
->groupBy(fn ($order) => $order->created_at->format('Y'))
->map(fn ($order) => $order->sum('total'));
$paid_orders = $collection->where('payment_confirmed', 1)
->groupBy(
fn ($order) => $order->payment_confirmed == false
? $order->year
: $order->created_at->format('Y')
)
->map(fn ($order) => $order->sum('total'));
return view('orders.index', compact('orders', 'unpaid_orders', 'paid_orders'));
}
Please note that the code content has been translated, and any code-specific elements remain in the original language.
英文:
Do $collection = Order::all();
once and use $collection
wherever you need it.
public function index(Order $order)
{
$collection = Order::all();
// OR
$collection = Order::select(['id', 'payment_confirmed', 'total', 'year', 'created_at'])->get();
$orders = $collection->groupBy(fn ($order) => $order->created_at->format('Y'))
->map(fn ($order) => $order->sum('total'));
$unpaid_orders = $collection->where('payment_confirmed', 0)
->groupBy(fn ($order) => $order->created_at->format('Y'))
->map(fn ($order) => $order->sum('total'));
$paid_orders = $collection->where('payment_confirmed', 1)
->groupBy(
fn ($order) => $order->payment_confirmed == false
? $order->year
: $order->created_at->format('Y')
)
->map(fn ($order) => $order->sum('total'));
return view('orders.index', compact('orders', 'unpaid_orders', 'paid_orders'));
}
答案2
得分: 0
要优化提供的代码中的查询,您可以在您的订单模型中定义作用域(scopes)。作用域允许您封装可重用的查询逻辑,使代码更容易优化和维护。下面是使用作用域优化的代码版本:
首先,让我们在您的订单模型中定义这些作用域:
class Order extends Model
{
// ...
public function scopeUnpaid($query)
{
return $query->where('payment_confirmed', 0);
}
public function scopePaid($query)
{
return $query->where('payment_confirmed', 1);
}
public function scopeGroupByYear($query)
{
return $query->groupBy(function ($order) {
return $order->created_at->format('Y');
});
}
}
现在,让我们修改index
方法以利用这些作用域:
public function index(Order $order)
{
$orders = Order::groupByYear()->get()->map(function ($year) {
return $year->sum('total');
});
$unpaid_orders = Order::unpaid()->groupByYear()->get()->map(function ($year) {
return $year->sum('total');
});
$paid_orders = Order::paid()->groupByYear()->get()->map(function ($year) {
return $year->sum('total');
});
return view('orders.index', compact('orders', 'unpaid_orders', 'paid_orders'));
}
通过使用作用域,我们可以直接在订单模型上链接必要的条件和分组逻辑,从而产生更干净和更优化的代码。
英文:
To optimize the query in the provided code using scopes, you can define scopes in your Order model. Scopes allow you to encapsulate reusable query logic, making it easier to optimize and maintain your code. Here's an optimized version of the code using scopes:
First, let's define the scopes in your Order model:
class Order extends Model
{
// ...
public function scopeUnpaid($query)
{
return $query->where('payment_confirmed', 0);
}
public function scopePaid($query)
{
return $query->where('payment_confirmed', 1);
}
public function scopeGroupByYear($query)
{
return $query->groupBy(function ($order) {
return $order->created_at->format('Y');
});
}
}
Now, let's modify the index method to utilize these scopes:
public function index(Order $order)
{
$orders = Order::groupByYear()->get()->map(function ($year) {
return $year->sum('total');
});
$unpaid_orders = Order::unpaid()->groupByYear()->get()->map(function ($year) {
return $year->sum('total');
});
$paid_orders = Order::paid()->groupByYear()->get()->map(function ($year) {
return $year->sum('total');
});
return view('orders.index', compact('orders', 'unpaid_orders', 'paid_orders'));
}
By using scopes, we can chain the necessary conditions and group by logic directly on the Order model, resulting in cleaner and more optimized code.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论