Kesalahan Anda adalah cara Anda menghitung _id untuk $group operator, khususnya second bagian:
second: { $subtract: [
{ $second: "$time" },
{ $mod: [
{ $second: "$time" },
timeBlock / 1000
]}
]}
Jadi, alih-alih membagi semua data Anda menjadi 10 timeBlock potongan panjang milidetik mulai dari new Date(end - 10 * timeBlock) , Anda membaginya menjadi 11 bagian mulai dari pembagi terdekat timeBlock .
Untuk memperbaikinya Anda harus terlebih dahulu menghitung delta = end - $time dan kemudian menggunakannya sebagai ganti $time yang asli untuk membuat _id . Anda .
Berikut adalah contoh dari apa yang saya maksud:
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) {
// ...
})
Saya juga menyarankan Anda untuk menggunakan nilai waktu mentah (dalam milidetik), karena itu jauh lebih mudah dan karena itu akan mencegah Anda membuat kesalahan. Anda dapat menggunakan time ke dalam timeParts setelah $group menggunakan $project operator.