gpt4 book ai didi

javascript - 时间序列和聚合框架(mongo)

转载 作者:可可西里 更新时间:2023-11-01 09:44:20 24 4
gpt4 key购买 nike

我正在尝试同步我在我的应用程序中运行的两个函数。第一个实时检查我在每个时间 block (例如每 10 秒)保存到 MongoDB 的文档数:

var getVolume = function(timeBlock, cb) {
var triggerTime = Date.now();
var blockPeriod = triggerTime - timeBlock;

Document.find({
time: { $gt: blockPeriod }
}).count(function(err, count) {
log('getting volume since ', new Date(blockPeriod), 'result is', count)
cb(triggerTime, count);
});
};

然后我有了第二个函数,每当我想为我的图表(前端)获取数据时都会使用它:

var getHistory = function(timeBlock, end, cb) {

Document.aggregate(
{
$match: {
time: {
$gte: new Date(end - 10 * timeBlock),
$lt: new Date(end)
}
}
},

// count number of documents based on time block
// timeBlock is divided by 1000 as we use it as seconds here
// and the timeBlock parameter is in miliseconds
{
$group: {
_id: {
year: { $year: "$time" },
month: { $month: "$time" },
day: { $dayOfMonth: "$time" },
hour: { $hour: "$time" },
minute: { $minute: "$time" },
second: { $subtract: [
{ $second: "$time" },
{ $mod: [
{ $second: "$time" },
timeBlock / 1000
]}
]}
},
count: { $sum: 1 }
}
},

// changing the name _id to timeParts
{
$project: {
timeParts: "$_id",
count: 1,
_id: 0
}
},

// sorting by date, from earliest to latest
{
$sort: {
"time": 1
}
}, function(err, result) {
if (err) {
cb(err)
} else {
log("start", new Date(end - 10 * timeBlock))
log("end", new Date(end))
log("timeBlock", timeBlock)
log(">****", result)
cb(result)
}
})
}

问题是我无法在图表和后端代码(getVolume 函数)上获得相同的值

我意识到来自 getHistory 的日志不是我期望的那样(日志如下):

start Fri Jul 18 2014 11:56:56 GMT+0100 (BST)
end Fri Jul 18 2014 11:58:36 GMT+0100 (BST)
timeBlock 10000
>**** [ { count: 4,
timeParts: { year: 2014, month: 7, day: 18, hour: 10, minute: 58, second: 30 } },
{ count: 6,
timeParts: { year: 2014, month: 7, day: 18, hour: 10, minute: 58, second: 20 } },
{ count: 3,
timeParts: { year: 2014, month: 7, day: 18, hour: 10, minute: 58, second: 10 } },
{ count: 3,
timeParts: { year: 2014, month: 7, day: 18, hour: 10, minute: 58, second: 0 } },
{ count: 2,
timeParts: { year: 2014, month: 7, day: 18, hour: 10, minute: 57, second: 50 } } ]

所以我希望 getHistory 应该从 start Fri Jul 18 2014 11:56:56 GMT+0100 (BST) 开始每 10 秒在 mongo 中查找一次数据 所以它看起来大致像这样:

11:56:56 count: 3
11:57:06 count: 0
11:57:16 count: 14
... etc.

待办事项:1. 我知道我应该在我的聚合函数中包含计数为 0 的情况,我猜这次被跳过了`

最佳答案

你的错误是你如何为 $group 运算符计算 _id,特别是它的 second 部分:

second: { $subtract: [
{ $second: "$time" },
{ $mod: [
{ $second: "$time" },
timeBlock / 1000
]}
]}

因此,不是将所有数据拆分为从 new Date(end - 10 * timeBlock) 开始的 10 timeBlock 毫秒长 block ,而是将其拆分为 11从 timeBlock 的最近约数开始的 block 。

要修复它,您应该首先计算 delta = end - $time,然后使用它代替原始的 $time 来构建您的 _id.

这是我的意思的一个例子:

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) {
// ...
})

我还建议您使用原始时间值(以毫秒为单位),因为这样更容易,而且可以防止您犯错误。您可以在 $group 之后使用 $project 运算符将 time 转换为 timeParts

关于javascript - 时间序列和聚合框架(mongo),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24823782/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com