mongodb - mongodb 随着时间的推移而获得的 yield

标签 mongodb time-series aggregation-framework

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

随着时间的推移流式传输值。
流数据以亚秒随机时间间隔收集到单个文档中。
流数据在 1 分钟时间组内进行分组和平均。
目标是将每个值与一小时后的一分钟平均值进行比较。

示例数据:

[
  {
    _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
  },
]

最佳答案

一种选择是使用 $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 随着时间的推移而获得的 yield ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74972717/

相关文章:

Java MongoDB 查询

macos - 无法使用 mongo 命令,显示在 mac 上找不到命令

python - 时间序列数据的滑动窗口训练/测试分割

node.js - Mongoose 聚合不返回最新文档

java - Mongodb,仅查找所有最新的映射记录

mongodb - 蒙戈 : select only one field from the nested object

pandas - pandas 六个月的日期范围

r - 在 R 中生成非平稳数据和 auto.arima

javascript - 在NodeJS中,如何从不同字段名的mongodb输出结果?

python - 寻找一种从 Python 代码中分片 MongoDB 集合的方法