我的Mongo数据库包含以下文档:
{
"timestamp": ISODate("2015-09-27T15:28:06.0Z"),
"value": '123'
},
{
"timestamp": ISODate("2015-09-27T15:31:06.0Z"),
"value": '737'
},
{
"timestamp": ISODate("2015-09-27T15:35:00.0Z"),
"value": '456'
},
{
"timestamp": ISODate("2015-09-27T15:40:20.0Z"),
"value": '789'
}
...等...
我想要做的是以5分钟的间隔聚合这些,而不是获得最新的(最新的时间戳)值每组5分钟。
所以基本上步骤是:
1)分成5分钟的小组
2)返回5分钟时间戳以及在此5分钟组内具有最新时间戳的文档的值
基于此以及我上面的文件,返回的文件应该是:
{
"timestamp": ISODate("2015-09-27T15:25:00.0Z"),
"value": '123'
},
{
"timestamp": ISODate("2015-09-27T15:35:00.0Z"),
"value": '456' // 456 has a newer timestamp than 737, which are in the same 5 minute range
},
{
"timestamp": ISODate("2015-09-27T15:40:00.0Z"),
"value": '789'
}
我尝试按照此处所述的5分钟间隔进行分组:https://stackoverflow.com/a/26814496/1007236
从那里开始,我无法找到如何在每个5分钟组内返回最新值。
我该怎么做?
答案 0 :(得分:1)
你可以通过一个非常简单的日期数学应用来解决这个问题:
db.collection.aggregate([
{ "$sort": { "timestamp": 1 } },
{ "$group": {
"_id": {
"$add": [
{ "$subtract": [
{ "$subtract": [ "$timestamp", new Date(0) ] },
{ "$mod": [
{ "$subtract": [ "$timestamp", new Date(0) ] },
1000 * 60 * 5
]}
]},
new Date(0)
]
},
"value": { "$first": "$value" }
}}
])
基本原则是找到模($mod
)或"余数"从时间开始,间隔为五分钟,并从基准时间中减去。这轮将在五分钟内完成。
当然另一部分是你$sort
,以确保最小的原始"时间戳"排序"价值"在"顶部"。
其他部分是$subtract
" epoch"将日期作为另一个日期的BSON日期,然后您会收到一个"整数"结果。类似的部分是添加($add
)"整数"到BSON日期类型以接收另一个BSON日期。
结果是BSON Date对象四舍五入到您使用数学的区间。
1000毫秒X 60秒X 5分钟。