Votre erreur est la façon dont vous calculez _id
pour $group
opérateur, en particulier son second
partie :
second: { $subtract: [
{ $second: "$time" },
{ $mod: [
{ $second: "$time" },
timeBlock / 1000
]}
]}
Ainsi, au lieu de diviser toutes vos données en 10 timeBlock
morceaux de millisecondes à partir de new Date(end - 10 * timeBlock)
, vous le divisez en 11 morceaux à partir du diviseur le plus proche de timeBlock
.
Pour résoudre ce problème, vous devez d'abord calculer delta = end - $time
puis utilisez-le à la place du $time
d'origine pour construire votre _id
.
Voici un exemple de ce que je veux dire :
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) {
// ...
})
Je vous recommande également d'utiliser des valeurs de temps brutes (en millisecondes), car c'est beaucoup plus facile et cela vous évitera de faire une erreur. Vous pouvez lancer time
dans timeParts
après $group
en utilisant $project
opérateur.