gpt4 book ai didi

mongodb - 如何规范化/减少 mongoDB 中的时间数据?

转载 作者:可可西里 更新时间:2023-11-01 09:32:06 25 4
gpt4 key购买 nike

我在 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”上的每个“端口名称”随时间的值进行平均。

那么如何在上面的映射函数中包含端口名称呢?发出的键是否应该是我稍后拆分的复合“array_serial、PortName、DateTime”值?或者我应该使用查询功能来查询每个不同的序列号、端口和时间?我是否正确地将这些数据存储在数据库中?

此外,据我所知,这些数据被保存到它自己的集合中,用这个平均数据替换集合中的数据的标准做法是什么?


这就是你说的 Asya 吗?因为它没有将四舍五入到较低 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 来执行此操作,这将真正帮助我。

最佳答案

以下是您可以在聚合框架中执行此操作的方法。我正在使用一个小的简化——我只对年、月和日期进行分组——在你的情况下,你需要添加小时和分钟以进行更细粒度的计算。如果您得到的数据样本中的点分布不均匀,您还可以选择是否进行加权平均。

project={"$project" : {
"year" : {
"$year" : "$DateTime"
},
"month" : {
"$month" : "$DateTime"
},
"day" : {
"$dayOfWeek" : "$DateTime"
},
"array_serial" : 1,
"Port Name" : 1,
"metric" : 1
}
};
group={"$group" : {
"_id" : {
"a" : "$array_serial",
"P" : "$Port Name",
"y" : "$year",
"m" : "$month",
"d" : "$day"
},
"avgMetric" : {
"$avg" : "$metric"
}
}
};

db.metrics.aggregate([project, group]).result

我用一些随机样本数据运行它并得到了这种格式的东西:

[
{
"_id" : {
"a" : "12345",
"P" : "CL1-B",
"y" : 2012,
"m" : 9,
"d" : 6
},
"avgMetric" : 100.8
},
{
"_id" : {
"a" : "12345",
"P" : "CL1-B",
"y" : 2012,
"m" : 9,
"d" : 7
},
"avgMetric" : 98
},
{
"_id" : {
"a" : "12345",
"P" : "CL1-A",
"y" : 2012,
"m" : 9,
"d" : 6
},
"avgMetric" : 105
}
]

如您所见,这是每个 array_serial、端口名称、年/月/日组合的一个结果。您可以使用 $sort 将它们按照您想要的顺序进行处理。

以下是您如何扩展项目步骤以包括小时和分钟,同时将分钟四舍五入为每五分钟的平均值:

{
"$project" : {
"year" : {
"$year" : "$DateTime"
},
"month" : {
"$month" : "$DateTime"
},
"day" : {
"$dayOfWeek" : "$DateTime"
},
"hour" : {
"$hour" : "$DateTime"
},
"fmin" : {
"$subtract" : [
{
"$minute" : "$DateTime"
},
{
"$mod" : [
{
"$minute" : "$DateTime"
},
5
]
}
]
},
"array_serial" : 1,
"Port Name" : 1,
"metric" : 1
}
}

希望您能够将其扩展到您的特定数据和要求。

关于mongodb - 如何规范化/减少 mongoDB 中的时间数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12662169/

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