gpt4 book ai didi

php - Symfony/Doctrine/MongoDB 获取每 N 个项目

转载 作者:IT老高 更新时间:2023-10-28 13:29:34 25 4
gpt4 key购买 nike

我有一个数据集,其中包含每天每 5 秒的数据点。这将导致每天 17280 个项目的数据集。这个集合太大了,我希望它更小(我正在使用这些项目来绘制图表)。

由于图表的 x 轴随时间变化,我认为每个数据点 5 分钟的间隔就足够了。这将返回到每天 288 个数据点。少得多,足以制作图表。

我的 MongoCollection 如下所示:

{
"timestamp":"12323455",
"someKey":123,
"someOtherKey": 345,
"someOtherOtherKey": 6789
}

数据每 5 秒发布一次到数据库中。所以每个结果的时间戳会相差 5 秒。

由于我的 x 轴分为 5 分钟序列,我很想计算 someKeysomeOtherKeysomeOtherOtherkey 的平均值在这 5 分钟内。这个新的平均值将成为我图表中的数据点之一。

如何获得 1 天的所有数据点,每个数据点平均相隔 5 分钟? (每天 288 个数据点)。

至于现在,我从今天午夜开始选择每个文档:

$result = $collection
->createQueryBuilder()
->field('timestamp')->gte($todayMidnight)
->sort('timestamp', 'DSC')
->getQuery()
->execute();

如何过滤这个数据列表(在同一个查询中)以获取每 5 分钟的数据点(并且数据点是这 5 分钟内的点的平均值)?

doctrine 构建这个查询会很好,因为我在我的 symfony 应用程序中需要它。

编辑我试图在 mongoshell 工作中首先获得我的查询。正如评论中建议的那样,我应该开始使用 aggregation .

到目前为止,我所做的查询是基于在 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 秒内获取所有文档并计算列 someKeysomeOtherKeysomeOtherOtherKey

的平均值

如果我们以这个示例数据集为例:

{
"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'
}
}
])

Match 部分用于获取 Today Midnight(今天午夜的时间戳)之后的所有结果。

小组部分是最有趣的部分。在这里,我们循环遍历我们找到的每个文档,并每 300 秒(5 分钟)计算一次模数,然后用模数运算的最后结果填充属性时间戳。

Project 部分是从实际结果中删除 _id 所必需的,因为结果不再代表数据库中的某些内容。

给出此答案所基于的答案:

MongoDB - Aggregate max/min/average for multiple variables at once

How to subtract in mongodb php

MongoDB : Aggregation framework : Get last dated document per grouping ID

Doctrine 解决方案

$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
]
]
]
]);

关于php - Symfony/Doctrine/MongoDB 获取每 N 个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37321804/

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