我在 MongoDB 中存储了详细的性能数据,每个集合都是一种性能报告,每个文档都是阵列上端口在该时间点的测量值:
{
"DateTime" : ISODate("2012-09-28T15:51:03.671Z"),
"array_serial" : "12345",
"Port Name" : "CL1-A",
"metric" : 104.2
}
每个“array_serial”最多可以有 128 个不同的“端口名称”条目。
随着数据的老化,我希望能够在越来越长的时间跨度内对其进行平均:
- 最多 1 周:分钟
- 1 周至 1 个月:5 分钟
- 1 - 3 个月:15 分钟
等等。这是我平均时间的方法,以便减少它们:
var resolution = 5; // How many minutes to average over
var map = function(){
var coeff = 1000 * 60 * resolution;
var roundTime = new Date(Math.round(this.DateTime.getTime() / coeff) * coeff);
emit(roundTime, { value : this.metric, count: 1 } );
};
我将对 reduce 函数中的值和计数求和,并在 finalize 函数中获得平均值。
正如您所看到的,这将在省略“端口名称”值的时间内平均数据,并且我需要对每个“array_serial”上的每个“端口名称”随时间平均这些值。
那么如何在上面的 map 函数中包含端口名称呢?发射的键是否应该是我稍后拆分的复合“array_serial,PortName,DateTime”值?或者我应该使用查询功能来查询每个不同的串行、端口和时间?我是否正确地将这些数据存储在数据库中?
另外,据我所知,这些数据被保存到它自己的集合中,用这个平均数据替换集合中的数据的标准做法是什么?
这就是你的意思阿莎吗?因为它没有将四舍五入到下 5 分钟的文档分组(顺便说一句,我将 'DateTime' 更改为 'datetime'):
$project: {
"year" : { $year : "$datetime" },
"month" : { $month : "$datetime" },
"day" : { $dayOfMonth : "$datetime" },
"hour" : { $hour : "$datetime" },
"minute" : { $mod : [ {$minute : "$datetime"}, 5] },
array_serial: 1,
port_name: 1,
port_number: 2,
metric: 1
}
据我所知,“$mod”运算符将返回分钟的剩余部分除以五,对吗?
如果我可以让聚合框架而不是 mapreduce 来执行此操作,这将真的对我有帮助。