在MongoDB中如何计算值随时间的变化?

Streaming values over time.
Streaming data is collected at sub-second random time intervals into individual documents.
Streamed data is grouped and averaged over 1 minute time group.
Goal is to compare each value to the one minute average one hour later.

示例数据:

[
  {
    _id: ObjectId("63a318c36ccc42d2330fae5e"),
    timestamp: ISODate("2022-12-21T14:30:31.172Z"),
    value: 3.8
  },
  {
    _id: ObjectId("63a318c46ccc42d2330fae8d"),
    timestamp: ISODate("2022-12-21T14:30:32.189Z"),
    value: 4.0
  },
  {
    _id: ObjectId("63a318c36ccc42d2330fae5e"),
    timestamp: ISODate("2022-12-21T15:30:14.025Z"),
    value: 5.0
  },  
  {
    _id: ObjectId("63a318c36ccc42d2330fae5e"),
    timestamp: ISODate("2022-12-21T15:30:18.025Z"),
    value: 5.5
  }
]

按一分钟组分组和求平均值的值:

{$group:{_id:{
        "code": "$code",
        "year": { "$year": "$timestamp" },
        "dayOfYear": { "$dayOfYear": "$timestamp" },
        "hour": { "$hour": "$timestamp" },
        "minute":{$minute:"$timestamp"}
        },
        value:{$avg:"$value"},
        timestamp:{$first:"$timestamp"},

这接近目标,但汇总了一小时间隔内的所有价格:

{$group:{_id:{
        "code": "$code",
        "year": { "$year": "$timestamp" },
        "dayOfYear": { "$dayOfYear": "$timestamp" },
        "hour": { "$hour": "$timestamp" }
        },
        value:{$first:"$value"},
        valueLast:{$last:"$value"},     
        timestamp:{$first:"$timestamp"},
        }
},

相反,我希望查看各个文档中的更改 也就是说,15:30的14:30值是多少,16:35的15:35值是多少: 如何将每个文档的值与一小时后的值进行比较?

[
  {
    _id: ObjectId("63a318c36ccc42d2330fae5e"),
    timestamp: ISODate("2022-12-21T14:30:31.172Z"),
    value: 3.8,
    valueLast: 5.25,
    gainPct: .382
  },
  {
    _id: ObjectId("63a318c46ccc42d2330fae8d"),
    timestamp: ISODate("2022-12-21T14:30:32.189Z"),
    value: 4.0,
    valueLast: 5.25,
    gainPct: .313
  },
]

推荐答案

一种 Select 是使用时间范围为$setWindowFields的时间来执行此操作: 它允许您按code分组、按cleanTimeStamp排序,并对当前文档(上下文中的每个文档)(时间)范围内的所有文档执行累加函数($avg):

db.collection.aggregate([
  {$set: {
      cleanTimeStamp: {
        $dateTrunc: {
          date: "$timestamp",
          unit: "minute"
        }
      }
  }},
  {$setWindowFields: {
      partitionBy: "$code",
      sortBy: {cleanTimeStamp: 1},
      output: {
        valueLast: {
          $avg: "$value",
          window: {range: [59, 60], unit: "minute"}
        }
      }
  }},
  {$set: {
      gainPct: {$round: [{$divide: [{$subtract: ["$valueLast", "$value"]}, "$value"]}, 3]},
      cleanTimeStamp: "$$REMOVE"
    }
  }
])

看看它在playground example号公路上是如何工作的

我不清楚您是想要每个文档的结果,还是想要一个特定的时间戳.如果您只希望查询返回特定分钟的结果,则可以在第一步$match中再添加一个步骤,以将文档的上下文限制在所需的时间戳和时间戳之后的1小时之间.

Mongodb相关问答推荐

MongoDB聚合:将文档列表转换为列表

MongoDB Aggregate-如何在条件中替换字符串中的变量

会话的Mongo-go驱动程序版本.Copy()

在单个mongo文档中组合数组与聚合

如何将数组$拉到对象数组下

如何对嵌套在另一个数组中的数组中的字段执行查找?

MongoDB $lookup 查找字段值数组

如何对 MongoDB setWindowFields 中当前文档以外的文档进行操作

根据条件删除一些数组元素并将数组的大小更新为mongo中的另一个文件

在运算符 $map 中嵌入运算符 $exists

如何在 Spring-Data-MongoDB 中使用 $facet、$addFields 和 $function

MongoDB 更改流副本集限制

Mongo查询子文档的多个字段

如何使用原子操作在一个文档中切换布尔字段?

Mongoose 中不同集合的相同模式

什么是 mongodb 中的admin数据库?

Python - Pymongo 插入和更新文档

MongoDB + Node JS + 基于角色的访问控制 (RBAC)

在 mongodb 中插入当前日期时间

MongoDB:删除唯一约束