我有一系列具有ISODate对象的文档。我试图把它们分成45分钟的块。所以分钟0-45将是一组,分钟45-下一分钟30将是另一组。
我的第一个想法是划分时间,但由于这些不是unix时间戳,我无法使用ISODate进行数学计算。我的第二个想法是$计划出小时,分钟,天等等,但意识到当时间块跨越两个不同的日子时分组会很困难。
# This doesn't work since you cant do the division.
query = [
{
"$match": {
'_id.t': {
'$gte': new Date(2014, 1, 1, 1, 0, 0),
'$lte': new Date(2014, 6, 1, 1, 0, 0)
}
}
},
{
"$project": {
"milliseconds": { '$millisecond': '$_id.t' }
}
},
{
"$project": {
"timeblock": {
"$divide": [
'$milliseconds', 900000
]
}
}
},
{
"$group": { "_id": { "timeblock": "$timeblock" } }
}
]
答案 0 :(得分:7)
我认为以下可以解决问题:
var baseDate = new Date(2014, 09, 17, 14, 25, 0); // any value as you want
var startDate = new Date(2014, 09, 17, 14, 25, 0);
var endDate = new Date(2014, 09, 20, 14, 25, 0);
var divisor = 45 * 60 * 1000; // milliseconds of 45 minutes
db.cc.aggregate([ {
$match : {
date : {
$gte : startDate,
$lt : endDate
}
}
}, {
$group : {
_id : {
$subtract : [ "$date", {
$mod : [ {
$subtract : [ "$date", baseDate ]
}, divisor ]
} ]
},
dates : {
$push : "$date"
}
}
} ]).pretty();
分组说明:
_id : {
$subtract : [ "$date", { /* start date of each block */
$mod : [ { /* remainder */
$subtract : [ "$date", baseDate ] /* offset */
}, divisor ]
} ]
},