我有一个数据集,每天每5秒包含一个数据点。这将导致每天有17280个项目的数据集。这个集合太大了,我希望它更小(我用这些项目来画一张图)。
由于图表的x轴是随时间变化的,我认为每个数据点5分钟的间隔就足够了。这将返回到每天288个数据点。少了很多,好得足以制作一张图。
我的MongoCollection看起来像这样:
{
"timestamp":"12323455",
"someKey":123,
"someOtherKey": 345,
"someOtherOtherKey": 6789
}
数据每隔5秒就会被发布到数据库中。因此,每个结果的时间戳将相差5秒。
由于我的x轴被划分为5分钟序列,我想计算这5分钟内someKey
、someOtherKey
和someOtherOtherkey
的平均值。这个新的平均值将是我图表中的数据点之一。
如何在平均间隔5分钟的情况下获得1天的所有数据点?(每天288个数据点)。
就目前而言,我正在从今天午夜开始选择每一份文件:
$result = $collection
->createQueryBuilder()
->field('timestamp')->gte($todayMidnight)
->sort('timestamp', 'DSC')
->getQuery()
->execute();
如何过滤此数据列表(在同一查询中)以获得每5分钟的数据点(数据点是这5分钟内的平均值)?
如果能用原则构建这个查询,那就太好了,因为我在symfony应用程序中需要它。
编辑我试着让我的查询首先在mongoshell中工作。正如在评论中建议的那样,我应该开始使用聚合。
到目前为止,我提出的问题是基于stackoverflow 提出的另一个问题
这是当前的查询:
db.Pizza.aggregate([
{
$match:
{
timestamp: {$gte: 1464559200}
}
},
{
$group:
{
_id:
{
$subtract: [
"$timestamp",
{"$mod": ["$timestamp", 300]}
]
},
"timestamp":{"$first":"$timestamp"},
"someKey":{"$first":"$someKey"},
"someOtherKey":{"$first":"$someOtherKey"},
"someOtherOtherKey":{"$first":"$someOtherOtherKey"}
}
}
])
这个查询将给我从今天午夜开始每300秒(5分钟)的最后结果。我希望它在这300秒内获取所有文档,并计算列someKey
、someOtherKey
、someOtherOtherKey
的平均值
因此,如果我们以这个数据集为例:
{
"timestamp":"1464559215",
"someKey":123,
"someOtherKey": 345,
"someOtherOtherKey": 6789
},
{
"timestamp":"1464559220",
"someKey":54,
"someOtherKey": 20,
"someOtherOtherKey": 511
},
{
"timestamp":"1464559225",
"someKey":654,
"someOtherKey": 10,
"someOtherOtherKey": 80
},
{
"timestamp":"1464559505",
"someKey":90,
"someOtherKey": 51,
"someOtherOtherKey": 1
}
查询应返回2行,即:
{
"timestamp":"1464559225",
"someKey":277,
"someOtherKey": 125,
"someOtherOtherKey": 2460
},
{
"timestamp":"1464559505",
"someKey":90,
"someOtherKey": 51,
"someOtherOtherKey": 1
}
第一个结果是这样计算的:
Result 1 - someKey = (123+54+654)/3 = 277
Result 1 - someOtherKey = (345+20+10)/3 = 125
Result 1 - someOtherOtherKey = (6789+511+80)/3 = 2460
如何在具有聚合函数的mongoshell中进行此计算
根据stackoverflow上给出的答案,我成功地得到了我想要的东西。
这是我必须进行的一个大的聚合查询,以返回所有结果:
db.Pizza.aggregate([
{
$match:
{
timestamp: {$gte: 1464559200}
}
},
{
$group:
{
_id:
{
$subtract: [
'$timestamp',
{$mod: ['$timestamp', 300]}
]
},
timestamp: {$last: '$timestamp'},
someKey: {$avg: '$someKey'},
someOtherKey: {$avg: '$someOtherKey'},
someOtherOtherKey: {$avg: '$someOtherOtherKey'}
}
},
{
$project:
{
_id: 0,
timestamp: '$timestamp',
someKey: '$someKey',
someOtherKey:'$someOtherKey',
someOtherOtherKey:'$someOtherOtherKey'
}
}
])
比赛部分是为了在今天午夜(今天午夜的时间戳)之后获得每一个结果。
小组部分是最有趣的部分。在这里,我们循环浏览我们找到的每个文档,并每300秒(5分钟)计算一个模数,然后用模数运算的最后结果填充属性时间戳。
Project部分需要从实际结果中删除_id,因为结果不再代表数据库中的某些内容。
给定答案,此答案基于:
MongoDB-同时聚合多个变量的最大/最小/平均
如何在mongodb php 中进行减法
MongoDB:聚合框架:根据分组ID 获取最后日期的文档
条令解决方案
$collection->aggregate([
[
'$match' => [
'timestamp' => ['$gte' => 1464559200]
]
],
[
'$group' => [
'_id' => [
'$subtract' => [
'$timestamp',
[
'$mod' => ['$timestamp',300]
]
]
],
'timestamp' => [
'$last' => '$timestamp'
],
$someKey => [
'$avg' => '$'.$someKey
],
$someOtherKey => [
'$avg' => '$'.$someOtherKey
],
$someOtherOtherKey => [
'$avg' => '$'.$someOtherOtherKey
]
]
]
]);