https://github.com/summerblue/laravel-shop 帮我看看这个上面的代码有没有什么可以优化的

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 13
翟宇鑫

没什么不对的,活学活用,这里不会有什么问题的

3周前 评论
lijizheng (楼主) 3周前
翟宇鑫 (作者) 3周前
lijizheng (楼主) 3周前

keyBy下,在通过wherein查,查询后在foreach里处理好数据,拿主键id,通过case when更新,循环里不做单独查询、更新操作

3周前 评论
sanders

如果量大容易导致队列执行超时,可以考虑将数据分页查出来,分发到其他队列任务中处理。

3周前 评论
nff93
$items = $event->getOrder()->items()->with(['product'])->get();
foreach ($items as $item) {
 // 更新商品的评分和评价数
  $item->product->update([
    'rating' =>  bcdiv(
      bcadd(
          bcmul($item->product->rating, $item->product->review_count, 2),
          $item->rating,
          2
      ), 
      $item->product->review_count + 1, 
       2
     ),
    'review_count' => Db::raw('review_count + 1'),
  ]);
}
3周前 评论

如楼上可以考虑封装批量更新 不在循环里面执行更新语句

3周前 评论
陈先生

建议把 OrderItem 也做到 releation 里面做关联。然后不要get ,直接 each 更新。

2周前 评论

为啥知道 n + 1,还用 foreach 呢,把 product_id 取出来当成数组,用 in 查询

2周前 评论

直接计算平均评分啊,评论数+1,为啥还要通过数据库去计算

2周前 评论

为啥知道 n + 1,还用 foreach 呢,把 product_id 取出来当成数组,用 in 查询 这位朋友说的对,可以用whereIn查询出一组数据,然后使用数组id匹配的方式来进行更新。还补充一句,如果量大,可以使用分块+队列的方式,结合whereIn,就不用担心新能问题了。

2周前 评论

如果是数据量大,就不要用多层嵌套with取数据了,还不如用join查

    public function handle(OrderReviewed $event)
    {
        //取出当前子订单所有商品id
        $productIdArr = OrderItem::query()->where("order_id",$event->getOrder()->id)->pluck("product_id")->toArray();
        self::updateProduct($productIdArr);
        /*$renewIdArr = [];
        $productUniArr = array_unique($productIdArr);
        foreach ($productUniArr as $productId){
            $renewIdArr[] = $productId;
            if (50 == count($renewIdArr)){
                self::updateProduct($renewIdArr);
                $renewIdArr = [];
            }
        }
        if (count($renewIdArr)){
            self::updateProduct($renewIdArr);
        }*/
    }

    public static function updateProduct($productIdArr)
    {
        //根据商品id直接groupby统计所有商品id的评分和评价数
        $orderProductArr = OrderItem::query()
            ->whereIn('product_id', $productIdArr)
            ->whereNotNull('reviewed_at')
            ->whereHas('order', function ($query) {
                $query->whereNotNull('paid_at');
            })
            ->groupBy("product_id")
            ->select([
                "product_id",
                DB::raw('count(*) as review_count'),
                DB::raw('avg(rating) as rating')
            ])->get()->toArray();
        //拼接case when 批量更新
        $reviewCountStr = "";
        $ratingStr = "";
        $endProductIdArr = [];
        foreach ($orderProductArr as $orderProductOne){
            $endProductIdArr[] = $orderProductOne["product_id"];
            $reviewCountStr .= " when id = ".$orderProductOne["product_id"]." then " . $orderProductOne["review_count"];
            $ratingStr .= " when id = ".$orderProductOne["product_id"]." then " . $orderProductOne["rating"];
        }
        ProductModel::whereIn('id', $endProductIdArr)
            ->update([
                "review_count" => DB::raw("case ".$reviewCountStr." end"),
                "rating" => DB::raw("case ".$ratingStr." end"),
            ]);
    }
2周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!