我有一个MongoDB分析风格的集合.它包含带有timestamp字段和各种数据的文档。现在,我想得到一个时间序列,其中包含一个带有粒度参数的时间段的文档数量。
我目前正在使用这样的聚合框架(假设粒度为DAY):
db.collection.aggregate([{
$match: {
timestamp: {
$gte: start_time,
$lt: end_time
}
}
}, {
$group: {
_id: {
year: { $year: '$timestamp' },
month: { $month: '$timestamp' },
day: { $dayOfMonth: '$timestamp' }
},
count: { $sum: 1 }
}
}, {
$sort: {
_id: 1
}
}])这样,我每天都有一个count值。问题是,counts将取决于计算$dayOfMonth部件时使用的时区(每个count从00:00:000 UTC到23:59:999 UTC)。
我希望能够做到这一点,而不依赖于时区,但依赖于start_time。例如,如果我在世界协调时间07:00使用start_time,我将在协调世界时07:00每天获得counts,到第二天世界协调时间07:00。
TL;DR :,我想要这样的东西:id/campaigns
知道该怎么做吗?
发布于 2015-11-24 16:33:31
我找到了一个效果很好的解决方案。这不是很自然,但无论如何。
这样做的目的是根据startDate和行的日期计算一个“规范化”日期。我使用$mod运算符在startDate上获得毫秒+秒+小时(在一天粒度的情况下),然后使用$subtract从行的日期减去它。
下面是一个日期粒度的示例:
var startDate = ISODate("2015-08-25 13:30:00.000Z")
var endDate = ISODate("2015-08-27 13:30:00.000Z")
db.collection.aggregate([{
$match: {
timestamp: {
$gte: startDate,
$lt: endDate
}
}, {
$project: {
timestamp_normalized: {
$subtract: [
"$timestamp",
{
$mod: [
{ "$subtract": [ startDate, new Date("1970-01-01") ] },
1000 * 60 * 60 * 24
]
}
]
}
}
}, {
// now $group with $dayOfMonth
}])$mod部件计算00:00 UTC之后的startDate的小时+秒+毫秒,以毫秒为单位。
$subtract从原始时间戳中检索这些毫秒。
现在,如果我们考虑第二天13:30到13:30之间的间隔,我可以在我的normalized_timestamp字段上使用normalized_timestamp操作符来获取日期,并使用$group获取这些时间间隔的计数值。
编辑:--在创建查询之前计算要从规范化时间戳中移除的值甚至更容易,使用:
(startDate - new Date(0)) % (1000 * 60 * 60 * 24)
(一天的粒度)
然后直接从timestamp中减去这个值,而不是使用$mod。
https://stackoverflow.com/questions/33675576
复制相似问题