我在MongoDB中有一个集合,其文档 struct 如下:

    _id:6591f2fe8424cddac5b1d4aa
    captureTime:1704063737
    deviceId:200220
    sensorId:1431

我在Aggregate Group阶段有这个代码,它以1小时为间隔计算文档数量 组别:

{
"_id": {
  "sensorId":"$sensorId",
  "year": { "$year": { "$toDate": { "$multiply": ["$captureTime", 1000] } } },
  "month": { "$month": { "$toDate": { "$multiply": ["$captureTime", 1000] } } },
  "day": { "$dayOfMonth": { "$toDate": { "$multiply": ["$captureTime", 1000] } } },
  "hour": { "$hour": { "$toDate": { "$multiply": ["$captureTime", 1000] } } },
  "interval": {
      "$subtract": [
        {"$minute": { "$toDate": { "$multiply": ["$captureTime", 1000] } }},
        {"$mod": [{"$minute": { "$toDate": { "$multiply": ["$captureTime", 1000] } }}, 60]}
      ]
    }
},
"count": { "$sum": 1 },
"time_f": { "$first": { "$dateToString": {
  "format": "%Y:%m:%d %H:%M:%S", 
  "date": { "$toDate": { "$multiply": ["$captureTime", 1000] } } }}},
"time_l": { "$last": { "$dateToString": {
  "format": "%Y:%m:%d %H:%M:%S", 
  "date": { "$toDate": { "$multiply": ["$captureTime", 1000] } } }}},
"device_Id_f": {"$first": "$deviceId"},
"sensor_Id_f": {"$first": "$sensorId"},



}

输出文档如下

_id: Object
count: 336
time_f: "2024:01:01 00:00:20"
time_l: "2024:01:01 00:58:35"
device_Id_f: 200220
sensor_Id_f: 1431

_id: Object
count: 18
time_f: "2024:01:01 01:00:17"
time_l: "2024:01:01 01:56:18"
device_Id_f: 200220
sensor_Id_f: 1431
time_interval: "2024:01:01 02:00:00"

然而,在输出文件中,我想知道它所属的间隔.例如,如下所示:

_id: Object
count: 336
time_f: "2024:01:01 00:00:20"
time_l: "2024:01:01 00:58:35"
device_Id_f: 200220
sensor_Id_f: 1431
time_interval: "2024:01:01 01:00:00"

_id: Object
count: 18
time_f: "2024:01:01 01:00:17"
time_l: "2024:01:01 01:56:18"
device_Id_f: 200220
sensor_Id_f: 1431
time_interval: "2024:01:01 02:00:00"

我知道这是我可以在我的应用程序中通过python来做的事情,但我认为如果我可以在MongoDB中做这件事,那会更好.

推荐答案

一种 Select 是通过使用$dateTrunc$set步骤来简化它,以避免对每个文档进行相同的计算:

db.collection.aggregate([
  {$group: {
      _id: {
        sensorId: "$sensorId",
        interval: {$dateTrunc: {
            date: {$toDate: {$multiply: ["$captureTime", 1000]}},
            unit: "hour"
        }}
      },
      count: {$sum: 1},
      time_f: {$first: { $dateToString: {
          format: "%Y:%m:%d %H:%M:%S", 
          date: {$toDate: {$multiply: ["$captureTime", 1000] } } }}},
      time_l: {$last: {$dateToString: {
          format: "%Y:%m:%d %H:%M:%S", 
          date: {$toDate: {$multiply: ["$captureTime", 1000] } } }}},
      device_Id_f: {$first: "$deviceId"},
      sensor_Id_f: {$first: "$sensorId"},
  }},
  {$set: {
      _id: {
        sensorId: "$_id.sensorId",
        interval: {$dateToString: {format: "%Y:%m:%d %H:%M:%S", date: "$_id.interval"}},
        year: {$year: "$_id.interval"},
        month: {$month: "$_id.interval"},
        day: {$dayOfMonth: "$_id.interval"},
        hour: {$hour: "$_id.interval"}
      }
  }},
  {$set: {time_interval: "$_id.interval"}} // if you want it also outside of the `_id`
])

看看它是如何工作的mongoDB playground

  • 请求结果上的_id的格式不清楚...

Mongodb相关问答推荐

MongoDB - 来自先前匹配文档的聚合匹配字段

定期自动轮换 MongoDb 集合

如何使用指南针连接到 mongodb replicaset (k8s)

聚合 $accumulator + $project

如何在mongodb中级联删除文档?

使用MongoDB作为我们的主数据库,我应该使用单独的图数据库来实现实体之间的关系吗?

使用 mongodb 时是否需要规范化数据库?

Mongo C#忽略属性

哪个库最适合用于带有 Scala 的 MongoDB?

如何使用python将csv数据推送到mongodb

$lookup 结果 mongodb 的计数

带有 jQ​​uery Ajax/JSON 前端的 MongoDB 或 CouchDB 中间件

使用 Spring Security + Spring 数据 + MongoDB 进行身份验证

在 MongoDB 中合并两个集合

在 mongodb 中的索引列上查找重复项的快速方法

在 MongoDB 上分片 GridFS

如何在 Meteor 应用程序之间共享 MongoDB 集合?

如何使用 mgo 从 golang 中的 mongodb 集合中 Select 所有记录

Pymongo/bson:将 python.cursor.Cursor 对象转换为可序列化/JSON 对象

将日期从毫秒转换为 ISODate 对象