Laravel:在同一查询上应用不同的过滤器(优化)

时间:2014-07-02 16:43:19

标签: php mysql laravel

我必须对数据库进行一次查询,这会返回很多行(第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');
}

但我现在有四个可能很重的查询而不是一个。有没有办法解决我的第一个例子?我应该使用缓存吗?

1 个答案:

答案 0 :(得分:0)

是的,可以只进行一次查询以获取所有结果,然后过滤结果。

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

现在$finishedTripsIlluminate/Database/Eloquent/Collection的一个实例,其中有一个方法filter()可用于过滤结果

$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');

只需一行代码即可实现相同目的。