Laravel:对相同的查询应用不同的过滤器(优化)


Laravel: applying different filters on same query (optimization)

我必须对返回很多行(第1行)的数据库进行一次查询。我希望我只能进行一次查询,然后在不再次访问数据库的情况下对其应用各种过滤器。像这样:

$finishedTrips = Auth::user()->trips()->whereNotNull('distance');
$transport = Config::get('transport');
foreach($transport as $key => $value) {
    $sum = $finishedTrips->where('transport', '=', $value['id'])->sum('distance');
}

这不起作用,我花了一个小时才意识到我实际上需要这样做才能使它工作:

$transport = Config::get('transport');
foreach($transport as $key => $value) {
    $sum = Auth::user()->trips()->whereNotNull('distance')->where('transport', '=', $value['id'])->sum('distance');
}

但是我现在有四个潜在的繁重查询而不是一个。有办法修复我的第一个例子吗?我应该使用缓存吗?

是的,可以只做一个查询来获取所有结果,然后过滤结果。

$finishedTrips = Auth::user()->trips()->whereNotNull('distance')->get();

现在$finishedTrips是一个实例照亮/数据库/雄辩/收集,它有一个方法过滤器(),你可以用它来过滤结果

$transports = Config::get('transport');
foreach($transports as $transport) {
    $filteredList = $finishedTrips->filter(function ($t) use($transport) {
        return $t->transport == $transport['id'];
    });
    $sum = array_sum($filteredList->lists('distance'));
}

但这是一个非常糟糕的方法。相反,您应该使用一个查询,按transport分组并对distance求和。

// Code not tested but you get the idea
Trips::where('user_id', Auth::user()->id)->groupBy('transport')->sum('distance');