Lỗi của bạn là cách bạn tính toán _id
cho $group
toán tử, cụ thể là second
của nó phần:
second: { $subtract: [
{ $second: "$time" },
{ $mod: [
{ $second: "$time" },
timeBlock / 1000
]}
]}
Vì vậy, thay vì chia nhỏ tất cả dữ liệu của bạn thành 10 timeBlock
đoạn dài mili giây bắt đầu từ new Date(end - 10 * timeBlock)
, bạn đang chia nó thành 11 phần bắt đầu từ ước số gần nhất của timeBlock
.
Để khắc phục, trước tiên bạn nên tính toán delta = end - $time
và sau đó sử dụng nó thay vì $time
ban đầu để xây dựng _id
của bạn .
Đây là một ví dụ về ý tôi muốn nói:
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) {
// ...
})
Tôi cũng khuyên bạn nên sử dụng các giá trị thời gian thô (tính bằng mili giây), vì nó dễ dàng hơn nhiều và vì nó sẽ giúp bạn không mắc lỗi. Bạn có thể truyền time
vào timeParts
sau $group
sử dụng $project
nhà điều hành.