我试图弄清楚如何在指定日期范围内的所有日期执行MongoDB集合中的事件计数。
MongoDB中的示例文档架构:
{
eventNum: 1234,
startDate:ISODate("2014-01-01"),
endDate: ISODate("2014-01-04")
eventType: System Crash
}
{
eventNum: 4567,
startDate: ISODate("2014-01-04"),
endDate: ISODate("2014-01-05")
eventType: Maintenance
}
我想要的是日期范围:
1/1/2014 - 1/6/2014
此范围内每天的总计数事件是多少?
结果将是:
1/1/2014: 1
1/2/2014: 1
1/3/2014: 1
1/4/2014: 2
1/5/2014: 1
1/6/2014: 0
我的问题实际上在于被跟踪的数据不是基于个人日的事实,这将允许我按日期执行基本聚合。事件有开始和结束日期。
答案 0 :(得分:2)
不幸的是,更多mapReduce问题,否则您无法发出使其工作所需的日期。
db.events.mapReduce(
function() {
var oneDay = ( 1000 * 60 * 60 * 24 ),
start = this.startDate.valueOf()
- ( this.startDate.valueOf() % oneDay ),
end = ((this.endDate.valueOf()
- ( this.endDate.valueOf() % oneDay )) + oneDay);
for ( var day = start; day < end; day += oneDay ) {
emit ( new Date( day ), 1 );
}
},
function(key, values) {
return Array.sum( values );
},
{
"query": {
"startDate": { "$gte": new Date("2014-01-01") },
"endDate": { "$lt": new Date("2014-01-06") }
},
"out": { "inline": 1 }
}
)
如果你真的想要在日期范围内不存在的事件的零值,你可以改变一点:
db.events.mapReduce(
function() {
var oneDay = ( 1000 * 60 * 60 * 24 ),
start = this.startDate.valueOf()
- ( this.startDate.valueOf() % oneDay ),
end = ((this.endDate.valueOf()
- ( this.endDate.valueOf() % oneDay )) + oneDay);
for ( var day = start; day < end; day += oneDay ) {
emit ( new Date( day ), 1 );
}
for ( var day = end; day <= ending.valueOf(); day += oneDay ) {
emit( new Date( day ), 0 );
}
},
function(key, values) {
return Array.sum( values );
},
{
"query": {
"startDate": { "$gte": new Date("2014-01-01") },
"endDate": { "$lt": new Date("2014-01-06") }
},
"scope": { "ending": new Date("2014-01-06") },
"out": { "inline": 1 }
}
)
它为您提供所需的输出:
"results" : [
{
"_id" : ISODate("2014-01-01T00:00:00Z"),
"value" : 1
},
{
"_id" : ISODate("2014-01-02T00:00:00Z"),
"value" : 1
},
{
"_id" : ISODate("2014-01-03T00:00:00Z"),
"value" : 1
},
{
"_id" : ISODate("2014-01-04T00:00:00Z"),
"value" : 2
},
{
"_id" : ISODate("2014-01-05T00:00:00Z"),
"value" : 1
},
{
"_id" : ISODate("2014-01-06T00:00:00Z"),
"value" : 0
}
]