Bak*_*ap4 6 php doctrine mongodb symfony doctrine-orm
我有一个数据集,每天每5秒包含一次数据点.这将导致每天17280件物品的数据集.这个集合太大了,我希望它更小(我使用这些项目来绘制图形).
由于图表的x轴随着时间的推移,我确定每个数据点的间隔为5分钟就足够了.这将每天返回288个数据点.制作图表要少得多,也足够好.
我的MongoCollection看起来像这样:
{
"timestamp":"12323455",
"someKey":123,
"someOtherKey": 345,
"someOtherOtherKey": 6789
}
Run Code Online (Sandbox Code Playgroud)
数据每5秒发布到数据库中.因此,每个结果的时间戳将相差5秒.
正如我的x轴是在5组分钟的序列分割我喜欢计算的平均值someKey,someOtherKey并且someOtherOtherkey在这些5分钟.这个新的平均值将是我图表中的数据点之一.
如何从1天获得所有数据点,每个平均5分钟相互之间?(每天288个数据点).
至于现在我从今天午夜开始选择每个文件:
$result = $collection
->createQueryBuilder()
->field('timestamp')->gte($todayMidnight)
->sort('timestamp', 'DSC')
->getQuery()
->execute();
Run Code Online (Sandbox Code Playgroud)
如何过滤此数据列表(在同一查询中)以获得每5分钟一次的数据点(并且数据点是这5分钟内点数的平均值)?
使用doctrine构建此查询会很好,因为我需要在我的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"}
}
}
])
Run Code Online (Sandbox Code Playgroud)
此查询将为我提供从今天午夜起每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
}
Run Code Online (Sandbox Code Playgroud)
查询应返回2行,即:
{
"timestamp":"1464559225",
"someKey":277,
"someOtherKey": 125,
"someOtherOtherKey": 2460
},
{
"timestamp":"1464559505",
"someKey":90,
"someOtherKey": 51,
"someOtherOtherKey": 1
}
Run Code Online (Sandbox Code Playgroud)
第一个结果计算如下:
Result 1 - someKey = (123+54+654)/3 = 277
Result 1 - someOtherKey = (345+20+10)/3 = 125
Result 1 - someOtherOtherKey = (6789+511+80)/3 = 2460
Run Code Online (Sandbox Code Playgroud)
如何使用聚合函数在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'
}
}
])
Run Code Online (Sandbox Code Playgroud)
匹配部分用于获取今天午夜(今天午夜的时间戳)之后的所有结果。
小组部分是最有趣的部分。在这里,我们循环遍历找到的每个文档,并每 300 秒(5 分钟)计算一次模数,然后用模数运算的最后结果填充属性时间戳。
项目部分对于从实际结果中删除 _id 是必要的,因为结果不再代表数据库中的某些内容。
给出此答案所基于的答案:
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
]
]
]
]);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
539 次 |
| 最近记录: |