有个需求需要按周划分统计数据,但是用$week、$year 统计出来的日期和尝试认知的数据不一致。主要问题是按周划分跨年问题、以及每周开始第一天应为周一而不是周日问题。
测试数据
db.test.insertOne({"date":ISODate("2020-12-31T00:00:00.000Z")})
db.test.insertOne({"date":ISODate("2021-01-01T00:00:00.000Z")})
db.test.insertOne({"date":ISODate("2021-01-03T00:00:00.000Z")})
db.test.insertOne({"date":ISODate("2021-01-04T00:00:00.000Z")})
db.test.aggregate([
{
$addFields:{
"year":{$year:{date:"$date",timezone: "+0800"}},
"week":{$week:{date:"$date",timezone: "+0800"}}
}
}
])
db.test.aggregate([
{
$addFields:{
"year":{$isoWeekYear:{date:"$date",timezone: "+0800"}},
"week":{$isoWeek:{date:"$date",timezone: "+0800"}}
}
}
])
$week、$year测试结果
使用$week、$year的结果
ISODate("2020-12-31T00:00:00.000Z") //周四 输出 2020年第52周
ISODate("2021-01-01T00:00:00.000Z") //周五 输出 2021年第0周
ISODate("2021-01-03T00:00:00.000Z") //周日 输出 2021年第1周
ISODate("2021-01-04T00:00:00.000Z") //周一 输出 2021年第1周
一个问题是$week每周的开始时间是周日和平时认为的周一不一致。第二个问题是跨年的周会被分开。
使用$isoWeek、$isoWeekYear
使用$isoWeek、$isoWeekYear的结果
ISODate("2020-12-31T00:00:00.000Z") //周四 输出 2020年第53周
ISODate("2021-01-01T00:00:00.000Z") //周五 输出 2020年第53周
ISODate("2021-01-03T00:00:00.000Z") //周日 输出 2020年第53周
ISODate("2021-01-04T00:00:00.000Z") //周一 输出 2021年第1周
验证结果iso处理方式和常识保持一致