Seu erro é como você está calculando
_id
para $group
operador, especificamente seu second
papel:second: { $subtract: [
{ $second: "$time" },
{ $mod: [
{ $second: "$time" },
timeBlock / 1000
]}
]}
Então, em vez de dividir todos os seus dados em 10
timeBlock
fragmentos de milissegundos começando em new Date(end - 10 * timeBlock)
, você está dividindo-o em 11 partes a partir do divisor mais próximo de timeBlock
. Para corrigi-lo, você deve primeiro calcular
delta = end - $time
e, em seguida, use-o em vez do $time
original para construir seu _id
. Aqui está um exemplo do que quero dizer:
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) {
// ...
})
Também recomendo que você use valores brutos de tempo (em milissegundos), porque é muito mais fácil e porque evitará que você cometa erros. Você pode transmitir
time
em timeParts
depois de $group
usando $project
operador.