Ditt fel är hur du beräknar _id
för $group
operatorn, närmare bestämt dess second
del:
second: { $subtract: [
{ $second: "$time" },
{ $mod: [
{ $second: "$time" },
timeBlock / 1000
]}
]}
Så istället för att dela upp all din data i 10 timeBlock
millisekunder långa bitar från new Date(end - 10 * timeBlock)
, delar du upp det i 11 bitar med början från närmaste delare av timeBlock
.
För att fixa det bör du först beräkna delta = end - $time
och använd den sedan istället för den ursprungliga $time
för att bygga ditt _id
.
Här är ett exempel på vad jag menar:
Document.aggregate({
$match: {
time: {
$gte: new Date(end - 10 * timeBlock),
$lt: new Date(end)
}
}
}, {
$project: {
time: 1,
delta: { $subtract: [
new Date(end),
"$time"
]}
}
}, {
$project: {
time: 1,
delta: { $subtract: [
"$delta",
{ $mod: [
"$delta",
timeBlock
]}
]}
}
}, {
$group: {
_id: { $subtract: [
new Date(end),
"$delta"
]},
count: { $sum: 1 }
}
}, {
$project: {
time: "$_id",
count: 1,
_id: 0
}
}, {
$sort: {
time: 1
}
}, function(err, result) {
// ...
})
Jag rekommenderar dig också att använda råtidsvärden (i millisekunder), eftersom det är mycket enklare och för att det kommer att hindra dig från att göra ett misstag. Du kan casta time
till timeParts
efter $group
med $project
operatör.