代码之家  ›  专栏  ›  技术社区  ›  Tutu Kaeen

加入Laravel的雄辩

  •  1
  • Tutu Kaeen  · 技术社区  · 7 年前

    我有一个访问模型,我得到的数据如下:

    $app_visits = Visit::select([
        'start',
        'end',
        'machine_name'
    ])->where('user_id', $chosen_id)->get();
    

    但我想为每次访问都加分。每次访问都有一个交互(但没有visit\u id(由于其他系统的原因,我无法添加它)。

    上一位开发人员是这样离开的:

    $interactions = Interaction::where([
        'machine_name' => $app_visit->machine_name,
    ])->whereBetween('date', [$app_visit->start, $app_visit->end])->get();
    
    $points = 0;
    foreach ($interactions as $interaction) {
        $points +=  (int)$interaction->app_stage;
    }
    $app_visits[$key]['points'] = $points
    

    但我真的不喜欢它,因为它又慢又乱。我只想在第一个查询中添加‘points’sum,只接触数据库一次。

    @按某人要求的数据库结构进行编辑:

    访问:

    |id | start | end | machine_name | user_id
    

    国际行动:

    |id | time | machine_name |  points
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   laminatefish    7 年前

    你可以用一些东西来雄辩。对于这种情况,可能最有用的是 select(DB::raw(sql...)) 因为您必须添加一些原始sql来检索计数。

    例如:

    return $query
        ->join(...)
        ->where(...)
        ->select(DB::raw(
            COUNT(DISTINCT res.id) AS count'
        ))
        ->groupBy(...);
    

    如果做不到这一点,我就用原始sql替换雄辩的。我们不得不这么做,因为我们的数据集是巨大的,而雄辩的模型构建被证明有点慢。

    使现代化 正如您添加的结构一样。为什么不根据 machine_name (甚至是使用原始sql计算点的自定义方法),并使用: Visits::with('interaction.visitPoints')->...blah ?

        2
  •  0
  •   Mkk    7 年前

    看看DB而不是雄辩: https://laravel.com/docs/5.6/queries

    用于更复杂和高效的查询。 还可以将原始SQL用于此外观。