有一对夫妇的接近这取决于其输出格式最适合您需要的方法。主要的注意事项是,使用"aggregation framework"本身,您实际上不能返回“投射”日期,但可以在处理API中的结果时获取易于重构为对象的值。
第一种方法是使用现有的"Date Aggregation Operators"到聚合框架:
db.collection.aggregate([
{ "$match": {
"time": { "$gte": startDate, "$lt": endDate }
}},
{ "$group": {
"_id": {
"year": { "$year": "$time" },
"dayOfYear": { "$dayOfYear": "$time" },
"hour": { "$hour": "$time" },
"minute": {
"$subtract": [
{ "$minute": "$time" },
{ "$mod": [ { "$minute": "$time" }, 10 ] }
]
}
},
"count": { "$sum": 1 }
}}
])
它返回一个包含所有你想要的“日期”的值_id
复合键。或者,如果只是在“小时”内,那么只需使用“分钟”部分,并根据您的量程选择的startDate
计算实际日期。
或者您可以使用普通的“日期数学”来获得自“时代”以来可以再次被直接馈送到日期构造器的毫秒数。
db.collection.aggregate([
{ "$match": {
"time": { "$gte": startDate, "$lt": endDate }
}},
{ "$group": {
"_id": {
"$subtract": [
{ "$subtract": [ "$time", new Date(0) ] },
{ "$mod": [
{ "$subtract": [ "$time", new Date(0) ] },
1000 * 60 * 10
]}
]
},
"count": { "$sum": 1 }
}}
])
在任何情况下,你不想做的事是实际应用$group
之前使用$project
。作为一个“流水线阶段”,$project
必须“循环”所有选定的文件并“转换”内容。
这需要时间,并且增加了查询的执行总数。您可以直接申请$group
,如图所示。因为JavaScript函数实际上允许重铸为日期,但比聚合框架要慢,当然也可以不用,但是,如果你真的“纯”了一个Date
对象而没有后处理,那么你总是可以使用"mapReduce"。光标响应:
db.collection.mapReduce(
function() {
var date = new Date(
this.time.valueOf()
- (this.time.valueOf() % (1000 * 60 * 10))
);
emit(date,1);
},
function(key,values) {
return Array.sum(values);
},
{ "out": { "inline": 1 } }
)
最好的办法是使用虽然聚集,作为改造的响应是很容易的:
db.collection.aggregate([
{ "$match": {
"time": { "$gte": startDate, "$lt": endDate }
}},
{ "$group": {
"_id": {
"year": { "$year": "$time" },
"dayOfYear": { "$dayOfYear": "$time" },
"hour": { "$hour": "$time" },
"minute": {
"$subtract": [
{ "$minute": "$time" },
{ "$mod": [ { "$minute": "$time" }, 10 ] }
]
}
},
"count": { "$sum": 1 }
}}
]).forEach(function(doc) {
doc._id = new Date(doc._id);
printjson(doc);
})
然后你有你的间隔将输出与真实的Date
对象分组。
['$ mod'](http://docs.mongodb.org/manual/reference/operator/aggregation/mod/)运算符很容易做到这一点。 –