MongoDB 每日记录按小时汇总

MongoDB aggregation of daily records hourly basis

我有一个 collection 或以下格式的订单:

"createTime" : ISODate("2021-04-16T08:01:39.000Z"),
"statusDetails" : [ 
    {
        "createTime" : ISODate("2021-04-16T08:01:39.000Z"),
        "createUser" : "FOP-SYSTEM",
        "stateOccurTimeStr" : "2021-04-16 15:01:39",
        "status" : 27,
        "statusDesc" : "Shipped"
    }
]

where createTime is showing that when the order has been created
statusDetails.status = 27 showing that order has been shipped
statusDetails.createTime showing that when the order has been shipped

我需要的结果是这样的:

Order Date 0-4 Hours 4-8 Hours 8-12 Hours 12-24 Hours > 24 Hours Total Orders
01-Jan-21 15 10 4 1 1 31

这表明在“2021 年 1 月 1 日”创建订单后,

15 orders shipped between 0-4 hours, 
10 orders shipped between 4-8 hours, 
4 orders shipped between  8-12 hours 

等等。

到目前为止我所做的是:

db.orders.aggregate([
   { $unwind : "$statusDetails"},
   {$match: {"statusDetails.status": { "$exists": true, "$eq": 24 }}},
   {$project : { createTime: 1,statusDetails:1, 
      dateDiff: {"$divide" : [{ $subtract: ["$statusDetails.createTime","$createTime" ] },3600000]}}},
   {$sort:{"createTime":-1}}
   ])

但这是显示每条记录的时间差,但我需要分组依据

编辑 我已经更新了我的查询,现在它使用 $group 显示记录,但我仍然需要添加另一个管道来对当前数据进行分组。

db.orders.aggregate([
   
   { $unwind : "$statusDetails"},
   {$match: {"statusDetails.status": { "$exists": true, "$eq": 27 }}},
   {$project : { createTime: 1,statusDetails:1, dateDiff:{"$floor": {"$divide" : [{ $subtract: ["$statusDetails.createTime","$createTime" ] },3600000]}}}},
    { 
        $group: 
        { _id: {  year : { $year : "$createTime" }, month : { $month : "$createTime" }, day : { $dayOfMonth : "$createTime" }},
        shippedTime: { $push: "$dateDiff" },
        count: { $sum: 1 }
        } 
    },
   
   
   
   {$sort:{"createTime":-1}}
])
  • $unwind解构statusDetails数组
  • $match你的条件
  • $addFields 在等式中的日期计算时段的基础上添加 slot 字段并获得总计
  • $group by date 根据您的格式使用 $dateToStringslot
  • $sortslot 升序排列
  • $groupdate 并构造插槽数组并获得总订单
db.collection.aggregate([
  { $unwind: "$statusDetails" },
  { $match: { "statusDetails.status": 27 } },
  {
    $addFields: {
      slot: {
        $multiply: [
          {
            $floor: {
              $divide: [
                {
                  $abs: {
                    "$divide": [
                      { $subtract: ["$statusDetails.createTime", "$createTime"] },
                      3600000
                    ]
                  }
                },
                4
              ]
            }
          },
          4
        ]
      }
    }
  },
  {
    $group: {
      _id: {
        date: {
          $dateToString: {
            date: "$createTime",
            format: "%d-%m-%Y"
          }
        },
        slot: "$slot"
      },
      total: {
        $sum: 1
      }
    }
  },
  { $sort: { "_id.slot": 1 } },
  {
    $group: {
      _id: "$_id.date",
      hours: {
        $push: {
          slot: "$_id.slot",
          total: "$total"
        }
      },
      totalOrders: { $sum: "$total" }
    }
  }
])

Playground

结果将是:

[
  {
    "_id": "16-04-2021",
    "hours": [
      { "slot": 0, "total": 1 }, // from 0 to 4
      { "slot": 4, "total": 1 }, // from 4 to 8
      { "slot": 8, "total": 2 } // from 8 to 12
    ],
    "totalOrders": 4
  }
]