MongoDB 按时间间隔对结果进行分组

MongoDB group results by time interval

我有一个 collection 如下所示。

{
"field1":"value1",
"created_at":"2022-01-01T11:42:01Z"
},
{
"field1":"value2",
"created_at":"2022-01-01T11:22:15Z"
}

我需要按 15 分钟的时间间隔对结果进行分组,并从 collection 中投影如下结果。

[{
"from":"2022-01-01T11:15:00Z",
"to":"2022-01-01T11:30:00Z",
"count":1
},
{
"from":"2022-01-01T11:30:00Z",
"to":"2022-01-01T11:45:00Z",
"count":1
}]

我可以使用以下查询按 15 分钟的时间间隔获取计数。但我也想投影起始日期和截止日期。

db.collection.aggregate([
  { "$group": {
    "_id": {
      "year": { "$year": "$created_at" },
      "dayOfYear": { "$dayOfYear": "$created_at" },
      "hour": { "$hour": "$created_at" },
      "interval": {
        "$subtract": [ 
          { "$minute": "$created_at" },
          { "$mod": [{ "$minute": "$created_at"}, 15] }
        ]
      }
    }},
    "count": { "$sum": 1 }
  }}
])

你可以尝试一种方法,

  • $dateToParts 获取 created_at 日期的一部分
  • $group 通过 yearmonthdayhourinterval 根据 mod 和减法计算并得到总数
  • 要从间隔获取日期,可以使用 $dateFromParts 运算符,只需将 15 分钟添加到日期中。
db.collection.aggregate([
  {
    $addFields: {
      created_at: { $dateToParts: { date: "$created_at" } }
    }
  },
  {
    $group: {
      _id: {
        year: "$created_at.year",
        month: "$created_at.month",
        day: "$created_at.day",
        hour: "$created_at.hour",
        interval: {
          $subtract: [
            "$created_at.minute",
            { $mod: ["$created_at.minute", 15] }
          ]
        }
      },
      count: { $sum: 1 }
    }
  },
  {
    $project: {
      _id: 0,
      count: 1,
      from: {
        $dateFromParts: {
          year: "$_id.year",
          month: "$_id.month",
          day: "$_id.day",
          hour: "$_id.hour",
          minute: "$_id.interval"
        }
      },
      to: {
        $dateFromParts: {
          year: "$_id.year",
          month: "$_id.month",
          day: "$_id.day",
          hour: "$_id.hour",
          minute: { $add: ["$_id.interval", 15] }
        }
      }
    }
  }
])

Playground