MongoDB 聚合时间序列

标签 mongodb mongodb-query aggregation-framework

我正在使用 MongoDB 存储时间序列数据,其结构与此处解释的“面向文档的设计”类似:http://blog.mongodb.org/post/65517193370/schema-design-for-time-series-data-in-mongodb

目标是查询整个系统一天中最繁忙的前 10 分钟。每个文档使用 60 个子文档(每分钟 1 个)存储 1 小时的数据。每分钟存储嵌入在“vals”字段中的各种指标。我关心的指标是“订单”。示例文档如下所示:

{
        "_id" : ObjectId("54d023802b1815b6ef7162a4"),
        "user" : "testUser",
        "hour" : ISODate("2015-01-09T13:00:00Z"),
        "vals" : {
                "0" : {
                        "orders" : 11,
                        "anotherMetric": 15
                },
                "1" : {
                        "orders" : 12,
                        "anotherMetric": 20
                },
                .
                .
                .
        }
}

请注意系统中有很多用户。

我已经设法通过对以下组对象进行聚合来(某种程度上)展平结构:

group = {
    $group: {
        _id: {
            hour: "$hour"
        },
        0: {$sum: "$vals.0.orders"},
        1: {$sum: "$vals.1.orders"},
        2: {$sum: "$vals.2.orders"},
        .
        .
        .
    }
}

但这只给了我 24 个文档(每小时 1 个),其中包含该小时内每分钟的订单数量,如下所示:

{
    "_id" : {
            "hour" : ISODate("2015-01-20T14:00:00Z")
    },
    "0" : 282086,
    "1" : 239358,
    "2" : 289188,
    .
    .
    .
}

现在我需要以某种方式从中获取一天中最重要的 10 分钟,但我不确定如何获取。我怀疑它可以用 $project 来完成,但我不确定如何。

最佳答案

您可以聚合为:

  • $match 特定日期的文档。
  • 在查询之前构造$group$project对象。
  • $group$hour,累计每个小时的所有文档 数组中的分钟。将分钟保存在文档中的某个位置。
  • $project 一个变量 docs 作为所有文档的 $setUnion 小时。
  • $unwind 文档。
  • $sort顺序
  • $limit10 个文档,这是我们需要的。

代码:

var inputDate = new ISODate("2015-01-09T13:00:00Z");
var group = {};
var set = [];
for(var i=0;i<=60;i++){
    group[i] = {$push:{"doc":"$vals."+i,
                       "hour":"$_id.hour",
                       "min":{$literal:i}}};
    set.push("$"+i);
}
group["_id"] = {$hour:"$hour"};
var project = {"docs":{$setUnion:set}}

db.t.aggregate([
{$match:{"hour":{$lte:inputDate,$gte:inputDate}}},
{$group:group},
{$project:project},
{$unwind:"$docs"},
{$sort:{"docs.doc.orders":-1}},
{$limit:2},
{$project:{"_id":0,
           "hour":"$_id",
           "doc":"$docs.doc",
           "min":"$docs.min"}}
])

关于MongoDB 聚合时间序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28310237/

相关文章:

mongodb - 使用来自 Powershell 的 shell --eval 开关调用 MongoDB 更新时遇到问题

mongodb - 在mongodb中进行分组时如何使用条件计数?

PHP/MongoDB 使用聚合计算数组中的字符串

mongodb - 是否可以向 MongoDB 写入可区分的联合?

c# - 如何创建包含 $redact 的 c# mongodb 管道

php - 为什么我的 php 数组作为对象保存到 MongoDB,然后作为带有字符串化键的关联数组进行检索?

mongodb - 用户断言 : 1: Update query failed -- RUNNER_DEAD

Mongodb加入从String到ObjectId的_id字段

mongodb聚合转换为int

MongoDB:使用来自多个集合的数据进行过滤