GroupBy在Laravel中嵌套多个级别

时间:2019-02-26 19:50:08

标签: laravel collections group-by nested multi-level

我有一个嵌套的多级对象列表。 这是从有关系的雄辩查询中得出的。

一个地方有很多订单

订单包含许多详细信息和一个客户

一个细节有一个产品和一个交货期

[
  {
    "place_id": 1,
    "name": "A Building",
    "address": "A Street, A Ward, A City",
    "orders": [
      {
        "customer": {
          "id": 1,
          "name": "Peter",
          "phone": "011111111"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 1,
            "product": {
              "name": "A Cup of Tea"
            }
          }
        ]  
      },
      {
        "customer": {
          "id": 2,
          "name": "Mary",
          "phone": "022222222222"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 3,
            "product": {
              "name": "Glass of Milk Shake"
            }
          }
        ]  
      }

    ]
  },
  {
    "place_id": 2,
    "name": "B Building",
    "address": "B Street, B Ward, B City",
    "orders": [
      {
        "customer": {
          "id": 3,
          "name": "Catherine",
          "phone": "0333333333"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 2,
            "product": {
              "name": "A Cup of Coffee"
            }
          }
        ]  
      },
      {
        "customer": {
          "id": 4,
          "name": "Tom",
          "phone": "04444444444444"
        },
        "order_details": [
          {
            "period_id": 2,
            "period": {
              "id": 1,
              "start_time": "10:00:00",
              "end_time": "10:30:00"
            },
            "product_id": 1,
            "product": {
              "name": "A Cup of Tea"
            }
          }
        ]  
      }
    ]
  } 
]

我需要将此列表按“时期”分组,然后按“地点”分组

预期结果:

[ 
  {
    "id": 1,
    "start_time": "08:00:00",
    "end_time": "08:30:00",
    "places": [
    {
    "place_id": 1,
    "name": "A Building",
    "address": "A Street, A Ward, A City",
    "orders": [
      {
        "customer": {
          "id": 1,
          "name": "Peter",
          "phone": "011111111"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 1,
            "product": {
              "name": "A Cup of Tea"
            }
          }
        ]  
      },
      {
        "customer": {
          "id": 2,
          "name": "Mary",
          "phone": "022222222222"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 3,
            "product": {
              "name": "Glass of Milk Shake"
            }
          }
        ]  
      }
    ]
  },
  {
    "place_id": 2,
    "name": "B Building",
    "address": "B Street, B Ward, B City",
    "orders": [
      {
        "customer": {
          "id": 3,
          "name": "Catherine",
          "phone": "0333333333"
        },
        "order_details": [
          {
            "period_id": 1,
            "period": {
              "id": 1,
              "start_time": "08:00:00",
              "end_time": "08:30:00"
            },
            "product_id": 2,
            "product": {
              "name": "A Cup of Coffee"
            }
          }
        ]  
      }
    ]
  } 
    ]
  },
   {
    "id": 2,
    "start_time": "10:00:00",
    "end_time": "10:30:00",
    "places": [
    {
    "place_id": 2,
    "name": "B Building",
    "address": "B Street, B Ward, B City",
    "orders": [
      {
        "customer": {
          "id": 4,
          "name": "Tom",
          "phone": "04444444444444"
        },
        "order_details": [
          {
            "period_id": 2,
            "period": {
              "id": 1,
              "start_time": "10:00:00",
              "end_time": "10:30:00"
            },
            "product_id": 1,
            "product": {
              "name": "A Cup of Tea"
            }
          }
        ]  
      }

    ]
  } 
    ]
  }
]

这是我的详细代码:

class Place extends Model
{
    public function orderDetails()
    {
        return $this->hasManyThrough(OrderDetail::class, 
   Order::class,'place_id','order_id','id','id');
    }
}

class Period extends Model
{
    public function details()
    {
        return $this->hasMany(OrderDetail::class, 'period_id', 'id');
    }
}

class Order extends Model
{
    public function place()
    {
        return $this->belongsTo(Place::class, 'place_id', 'id');
    }

    public function user()
    {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }

    public function details()
    {
        return $this->hasMany(OrderDetail::class, 'order_id', 'id');
    }

}

class OrderDetail extends Model
{
    public function period()
    {
        return $this->belongsTo(Period::class, 'period_id', 'id');
    }

    public function product()
    {
        return $this->belongsTo(Product::class, 'product_id', 'id');
    }

    public function order()
    {
        return $this->belongsTo(Order::class, 'order_id', 'id');
    }
}


Place::with(['orderDetails', 'orderDetails.product', 'orderDetails.period', 'orderDetails.order.user'])->get()->toArray();

我正在使用laravel,因此最好使用laravel的收集助手来更快地解决此问题。 请帮我 。谢谢

已更新:

我使用了另一个查询和组 在OrderDetail模型中添加:

protected $appends = ['place_id'];
public function getPlaceIdAttribute()
{
  return $this->order->place_id;
}

然后使用此查询,我可以对句点而不是地点进行分组,但是它仅包含ID。

OrderDetail::with(['order','order.user','order.place','product','period'])->get()->groupBy(['period_id','place_id'])->toArray();

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。

OrderDetail::with(['order','order.user','order.place','product','period'])->get()->groupBy(['period.id','order.place.id'])->map(function ($periods) {
            $period = $periods->first()->first()->period;
            return [
                "start_time" => $period->start_time,
                "end_time" => $period->end_time,
                "places" => $periods->map(function ($places) {
                    $place = $places->first()->place;
                    return [
                        "name" => $place->name,
                        "address" => $place->address,
                        "details" => $places->toArray()
                    ];
                })->toArray()
            ];
        })->toArray();