mongodb聚合函数时间如果是date类型的 分组的话会出现时区相差8小时问题,因为$dayOfYear等函数是按照utc时间分组的 所以会有问题,
解决方法1:
时间地段用字符串存储,然后利用$substr来截取 年月日进行按天分组等 代码如下
db.main_test.aggregate(
{
$project: {
time: '$time',
timeFormat: { $dateToString: { format: "%Y-%m-%d", date: "$time" } },
timeYearStr: { $substr: ['$time', 0, 4] },
timeMonthStr: { $substr: ['$time', 5, 2] },
timeDayStr: { $substr: ['$time', 8, 2] },
year: { $year: "$time" },
month: { $month: "$time" },
day: { $dayOfMonth: "$time" },
request: '$request'
}
},
{
$match: {
time: { $gte: new Date('2017-03-13'), $lte: new Date('2017-03-15') }
}
},
{
$group: {
_id: { year: '$year', month: '$timeMonthStr', day: '$timeDayStr' },
time: { $last: "$time" },
timeFormat: { $last: "$timeFormat" },
timeYearStr: { $last: "$timeYearStr" },
timeMonthStr: { $last: "$timeMonthStr" },
timeDayStr: { $last: "$timeDayStr" },
totalReq: { $sum: "$request" }
}
},
{ $sort: { time: 1 } }
)
解决方法2:时间还是date类型 使用 $add:['$time',28800000]后再进分组
如下:
db.main_test.aggregate( { $project: { time: '$time', timeNew: { $substr:[{$add:['$time',28800000]},0,10]}, timeFormat: { $dateToString: { format: "%Y-%m-%d", date: "$time" } }, timeYearStr: { $substr: ['$time'.toLocaleString(), 0, 4] }, timeMonthStr: { $substr: ['$time', 5, 2] }, timeDayStr: { $substr: ['$time', 8, 2] }, year: { $year: "$time" }, month: { $month: "$time" }, day: { $dayOfMonth: {$add:['$time',28800000]} }, request: '$request' } }, { $match: { time: { $gte: new Date('2017-03-13'), $lte: new Date('2017-03-15') } } }, { $group: { _id: { year: '$year', month: '$timeMonthStr', day: '$day' }, day:{$last:'$day'}, timeNew:{$last:'$timeNew'}, time: { $last: "$time" }, timeFormat: { $last: "$timeFormat" }, timeYearStr: { $last: "$timeYearStr" }, timeMonthStr: { $last: "$timeMonthStr" }, timeDayStr: { $last: "$timeDayStr" }, totalReq: { $sum: "$request" } } }, { $sort: { time: 1 } } )
参考链接:https://docs.mongodb.com/manual/reference/operator/aggregation/substr/