我有一个日期时间字段和计数字段的集合:
{
_id: null,
datetime: new Date(),
count: 1234
}
我希望在24小时,7天和30天间隔内获得计数的总和。 结果必须如下:
{"sum": 100, "interval": "day"},
{"sum": 700, "interval": "week"},
{"sum": 3000, "interval": "month"}
修改
更抽象:我需要多个条件的组结果(在这种情况下 - 多个时间间隔)
MySQL示例:
SELECT
IF (time>CURRENT_TIMESTAMP() - INTERVAL 24 HOUR, 1, 0) last_day,
IF (time>CURRENT_TIMESTAMP() - INTERVAL 168 HOUR, 1, 0) last_week,
IF (time>CURRENT_TIMESTAMP() - INTERVAL 720 HOUR, 1, 0) last_month,
SUM(count) count
FROM table
GROUP BY last_day,
last_week,
last_month
答案 0 :(得分:17)
MongoDB的聚合框架可以使用date aggregation operators。因此,例如,$dayOfYear
运算符用于从分组中使用的日期获取该值:
db.collection.aggregate([
{ "$group": {
"_id": { "$dayOfYear": "$datetime" },
"total": { "$sum": "$count" }
}}
])
或者您可以使用日期数学方法。通过应用纪元日期,您可以将日期对象转换为可应用数学的数字:
db.collection.aggregate([
{ "$group": {
"_id": {
"$subtract": [
{ "$subtract": [ "$datetime", new Date("1970-01-01") ] },
{ "$mod": [
{ "$subtract": [ "$datetime", new Date("1970-01-01") ] },
1000 * 60 * 60 * 24
]}
]
},
"total": { "$sum": "$count" }
}}
])
如果你所追求的是从当前时间点开始的间隔,那么你想要的基本上是日期数学方法,并通过$cond
运算符在某些条件下工作:
db.collection.aggregate([
{ "$match": {
"datetime": {
"$gte": new Date(new Date().valueOf() - ( 1000 * 60 * 60 * 24 * 365 ))
}
}},
{ "$group": {
"_id": null,
"24hours": {
"$sum": {
"$cond": [
{ "$gt": [
{ "$subtract": [ "$datetime", new Date("1970-01-01") ] },
new Date().valueOf() - ( 1000 * 60 * 60 * 24 )
]},
"$count",
0
]
}
},
"30days": {
"$sum": {
"$cond": [
{ "$gt": [
{ "$subtract": [ "$datetime", new Date("1970-01-01") ] },
new Date().valueOf() - ( 1000 * 60 * 60 * 24 * 30 )
]},
"$count",
0
]
}
},
"OneYear": {
"$sum": {
"$cond": [
{ "$gt": [
{ "$subtract": [ "$datetime", new Date("1970-01-01") ] },
new Date().valueOf() - ( 1000 * 60 * 60 * 24 * 365 )
]},
"$count",
0
]
}
}
}}
])
它与SQL示例的方法基本相同,其中查询有条件地评估日期值是否在所需范围内,并决定是否将值添加到总和中。
此处的一个附加内容是额外的$match
阶段,用于限制查询仅针对那些可能在您要求的最大一年范围内的项目。这使得它比所提出的SQL好一点,因为可以使用索引来过滤掉这些值,并且您不需要"暴力"通过集合中的非匹配数据。
使用聚合管道时,最好使用$match
限制输入。
答案 1 :(得分:3)
有两种不同的方法可以做到这一点。一种是为每个范围发出单独的count()
查询。这非常简单,如果将datetime字段编入索引,则会很快。
第二种方法是使用与SQL示例类似的方法将它们全部合并到一个查询中。为此,您需要使用aggregate()
方法,创建$project
的管道,为新" last_day"," last_week&#创建0或1值34;和" last_month"字段,然后使用$group
运算符来完成总和。