0

一个关于使用 $month,$dayOfMonth 进行按月/日统计的BUG

情景如下:

按月,日进行统计分组:

db.test_tbl.aggregate([
{“$match”:{“CreateTime”:{$gte:ISODate(“2016-03-10T00:00:00.000+0800”),$lt:ISODate(“2016-03-11T00:00:00.000+0800”)}
}},
{“$group”:{
“_id”:{“cmonth”:{“$month”:”$CreateTime”},”cday”:{“$dayOfMonth”:”$CreateTime”}},
qty:{$sum:1}
}}
]);

得到以下结果:
—————————————————————————————————————————————–
{ “_id” : { “cmonth” : NumberInt(3), “cday” : NumberInt(9) }, “qty” : NumberInt(11)}
{ “_id” : { “cmonth” : NumberInt(3), “cday” : NumberInt(10) }, “qty” : NumberInt(14357)}

从上面可以看到,条件是 3/10 00:00:00 -3/11 00:00:00 统计的数据,但分组统计后出来了3/9号的数据。
但从下面统计:

db.test_tbl.aggregate([
{“$match”:{“CreateTime”:{$gte:ISODate(“2016-03-10T00:00:00.000+0800”),$lt:ISODate(“2016-03-11T00:00:00.000+0800”)}
}},
{“$group”:{
“_id”:null,
qty:{$sum:1}
}}
]);

得到的结果如下:(两次统计总量是对的)
—————————————————————————————————————————————–
{ “_id” : null, “qty” : NumberInt(14368)}

再做如下查询:

db.test_tbl.find({“CreateTime”:{$gte:ISODate(“2016-03-10T00:00:00.000+0800”),$lt:ISODate(“2016-03-10T08:00:00.000+0800”)}},{CreateTime:1}).sort({CreateTime:-1});
—————————————————————————————————————————————–
{ “_id” : NumberLong(258579), “CreateTime” : ISODate(“2016-03-10T07:42:56.063+0800”)}
{ “_id” : NumberLong(258578), “CreateTime” : ISODate(“2016-03-10T06:53:11.203+0800”)}
{ “_id” : NumberLong(258577), “CreateTime” : ISODate(“2016-03-10T06:53:11.156+0800”)}
{ “_id” : NumberLong(258576), “CreateTime” : ISODate(“2016-03-10T06:53:11.125+0800”)}
{ “_id” : NumberLong(258575), “CreateTime” : ISODate(“2016-03-10T06:53:11.094+0800”)}
{ “_id” : NumberLong(258574), “CreateTime” : ISODate(“2016-03-10T06:53:11.078+0800”)}
{ “_id” : NumberLong(258573), “CreateTime” : ISODate(“2016-03-10T06:53:11.063+0800”)}
{ “_id” : NumberLong(258572), “CreateTime” : ISODate(“2016-03-10T06:53:10.953+0800”)}
{ “_id” : NumberLong(258571), “CreateTime” : ISODate(“2016-03-10T06:53:10.938+0800”)}
{ “_id” : NumberLong(258570), “CreateTime” : ISODate(“2016-03-10T06:53:10.906+0800”)}
{ “_id” : NumberLong(258569), “CreateTime” : ISODate(“2016-03-10T06:53:10.438+0800”)}

可以看出,正好是11条,函数 $dayOfMonth 是基于 0时区来处理的,把0:00 — 8:00 时间内的数据计算到了前一天了。
这应该是MONGODB 的一个BUG ??