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

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

情景如下:

按月,日进行统计分组:

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 时间内的数据计算到了前一天了。

所以在统计查询时,条件与函数的时区要一致。比如上面的查询条件不用时区就没问题,如下:

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






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值