[英]gain over time in mongodb
How is change in a value over time calculated in mongodb?如何在 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.流式数据在 1 分钟时间组内进行分组和平均。
Goal is to compare each value to the one minute average one hour later.目标是将每个值与一小时后的一分钟平均值进行比较。
Example data:示例数据:
[
{
_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
}
]
values grouped and averaged in one minute groups:在一分钟组中分组和平均的值:
{$group:{_id:{
"code": "$code",
"year": { "$year": "$timestamp" },
"dayOfYear": { "$dayOfYear": "$timestamp" },
"hour": { "$hour": "$timestamp" },
"minute":{$minute:"$timestamp"}
},
value:{$avg:"$value"},
timestamp:{$first:"$timestamp"},
this gets close to the goal, but aggregates all the prices over an hour interval:这接近目标,但汇总了一个小时间隔内的所有价格:
{$group:{_id:{
"code": "$code",
"year": { "$year": "$timestamp" },
"dayOfYear": { "$dayOfYear": "$timestamp" },
"hour": { "$hour": "$timestamp" }
},
value:{$first:"$value"},
valueLast:{$last:"$value"},
timestamp:{$first:"$timestamp"},
}
},
Instead, I want to look at change in the individual documents That is, what is the 14:30 value at 15:30, and what is the 15:35 value at 16:35: How do I compare a value to one hour later for each document?相反,我想查看各个文档中的变化 即 15:30 的 14:30 值是多少,16:35 的 15:35 值是多少:How do I compare a value to one hour later每个文件?
[
{
_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
},
]
One option is to use $setWindowFields
with time range for this: It allows you to group by code
sort by cleanTimeStamp
and preform an accumulation function ( $avg
) on all document within a (time) range from your current document (each document in context):一种选择是为此使用带时间范围的
$setWindowFields
:它允许您按code
分组,按cleanTimeStamp
排序,并在当前文档(上下文中的每个文档)的(时间)范围内对所有文档执行累积 function( $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"
}
}
])
See how it works on the playground example在playground 示例中查看它是如何工作的
It is not clear to me if you want the result for each document or for a specific timestamp.如果您想要每个文档或特定时间戳的结果,我不清楚。 If you only want the query to return results for a specific minute, you can add one more step of
$match
, as a first step, to limit the context of your documents to be between the wanted timestamp and 1 hour after it.如果您只希望查询返回特定分钟的结果,您可以再添加一步
$match
作为第一步,以将文档的上下文限制在所需时间戳和它之后 1 小时之间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.