gpt4 book ai didi

javascript - 使用 mongodb 聚合框架计算频率

转载 作者:可可西里 更新时间:2023-11-01 10:43:50 25 4
gpt4 key购买 nike

我正在尝试根据 10 秒的间隔计算我的数据库中文档的频率。

这是我的数据库对象的样子:

[
{
created_at: "2014-03-31T22:30:48.000Z",
id: 450762158586880000,
_id: "5339ec9808eb125965f2eae1"
},
{
created_at: "2014-03-31T22:30:48.000Z",
id: 450762160407597060,
_id: "5339ec9808eb125965f2eae2"
},
{
created_at: "2014-03-31T22:30:49.000Z",
id: 450762163482017800,
_id: "5339ec9908eb125965f2eae3"
},
{
created_at: "2014-03-31T22:30:49.000Z",
id: 450762166367707140,
_id: "5339ec9908eb125965f2eae4"
},
{
created_at: "2014-03-31T22:30:50.000Z",
id: 450762167412064260,
_id: "5339ec9a08eb125965f2eae5"
}
]

我已经设法在给定的时间间隔内显示频率,但我想每 10 秒显示一次。所以最好我的 JSON 看起来像:

[
{
time_from: "2014-03-31T22:30:48.000Z",
time_to: "2014-03-31T22:30:58.000Z",
count: 6
},
{
time_from: "2014-03-31T22:30:58.000Z",
time_to: "2014-03-31T22:31:08.000Z",
count: 3
},
{
time_from: "2014-03-31T22:31:08.000Z",
time_to: "2014-03-31T22:31:18.000Z",
count: 10
},
{
time_from: "2014-03-31T22:31:18.000Z",
time_to: "2014-03-31T22:31:28.000Z",
count: 1
},
{
time_from: "2014-03-31T22:31:28.000Z",
time_to: "2014-03-31T22:31:38.000Z",
count: 3
}
]

这是我到目前为止所做的:

exports.findAll = function (req, res) {
db.collection(collection_name, function (err, collection) {
collection.find().toArray(function (err, items) {
collection.find().sort({"_id": 1}).limit(1).toArray(function (err, doc) {
var interval = 100000; // in milliseconds
var startTime = doc[0].created_at;
var endTime = new Date(+startTime + interval);

collection.aggregate([
{$match: {"created_at": {$gte: startTime, $lt: endTime}}},
{$group: {"_id": 1, "count":{$sum: 1}}}
], function(err, result){
console.log(result);
res.send(result);
});
});
})
});
};

结果是这样的:

[
{
_id: 1,
count: 247
}
]

编辑:

collection.aggregate([
{ $group: {
_id: {
year: { '$year': '$created_at'},
month: {'$month': '$created_at'},
day: {'$dayOfMonth': '$created_at'},
hour: {'$hour': '$created_at'},
minute: {'$minute': '$created_at'},
second: {'$second': '$created_at'}
},
count: { $sum : 1 }
} }
], function (err, result) {
console.log(result);
res.send(result);
});

结果是:

[
{
_id: {
year: 2014,
month: 3,
day: 31,
hour: 22,
minute: 37,
second: 10
},
count: 6
}, ...

新的进度,现在如何以10秒为间隔显示?

最佳答案

如果它只是在 10 秒的间隔内获取东西,您可以做一些数学运算并通过聚合运行它:

db.collection.aggregate([
{ "$group": {
"_id": {
"year": { "$year": "$created_at" },
"month":{ "$month": "$created_at" },
"day": { "$dayOfMonth": "$created_at" },
"hour": { "$hour": "$created_at" },
"minute": { "$minute": "$created_at" },
"second": { "$subtract": [
{ "$second": "$created_at" },
{ "$mod": [
{ "$second": "$created_at" },
10
]}
]}
},
"count": { "$sum" : 1 }
}}
])

因此,通过一点模 10 数学运算,可以将事情分解为每分钟 10 秒的间隔。

我认为这是合理的,并且会是最快的运行者,因为它使用聚合。如果您确实需要如图所示的序列从最初匹配的时间开始运行 10 秒,那么您可以使用 mapReduce 完成该过程:

首先是一个映射器:

var mapper = function () {

if ( this.created_at.getTime() > ( last_date + 10000 ) ) {
if ( last_date == 0 ) {
last_date = this.created_at.getTime();
} else {
last_date += 10000;
}
}

emit(
{
start: new Date( last_date ),
end: new Date( last_date + 10000 )
},
this.created_at
);

}

所以这将在 10 秒间隔内发出日期,从第一个日期开始,然后每次发现超出范围的内容时增加间隔

现在你需要一个reducer:

var reducer = function (key, values) {
return values.length;
};

很简单。返回传入的数组长度即可。

因为 mapReduce 的工作方式是这样的,任何没有超过一个值的东西都不会传递给 reducer,所以用 finalize 清理一下:

var finalize = function (key, value) {
if ( typeof(value) == "object" ) {
value = 1;
}
return value;
};

然后运行它就可以得到结果了。请注意传递要在映射器中使用的全局变量的“作用域”部分:

db.collection.mapReduce(
mapper,
reducer,
{
"out": { "inline": 1 },
"scope": { "last_date": 0 },
"finalize": finalize
}
)

每种方法可能会给出略有不同的结果,但这就是重点。这取决于您实际想要使用哪一个。


考虑到您的评论,您可以“检查”任一语句的输出并按原样以编程方式“填补空白”。我通常更喜欢该选项,但这不是我的程序,而且我不知道您要从此查询中检索的系列有多大。

在服务器端,你可以修补“映射器”来做这样的事情:

var mapper = function () {

if ( this.created_at.getTime() > ( last_date + 10000 ) ) {

if ( last_date == 0 ) {
last_date = this.created_at.getTime();
} else {
// Patching for empty blocks
var times = Math.floor(
( this.created_at.getTime() - last_date ) / 10000
);

if ( times > 1 ) {
for ( var i=1; i < times; i++ ) {
last_date += 10000;
emit(
{
start: new Date( last_date ),
end: new Date( last_date + 10000 )
},
0
);
}
}
// End patch
last_date += 10000;
}
}

emit(
{
start: new Date( last_date ),
end: new Date( last_date + 10000 )
},
this.created_at
);

}

关于javascript - 使用 mongodb 聚合框架计算频率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22860956/

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