MongoDB聚合时间序列

MongoDB聚合时间序列,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我使用MongoDB来存储时间序列数据,其结构与此处解释的“面向文档的设计”类似: 目标是查询整个系统中一天中最繁忙的前10分钟。每个文档使用60个子文档(每分钟1个)存储1小时的数据。每分钟存储嵌入“VAL”字段中的各种指标。我关心的指标是“订单”。示例文档如下所示: { "_id" : ObjectId("54d023802b1815b6ef7162a4"), "user" : "testUser", "hour" : ISODate("201

我使用MongoDB来存储时间序列数据,其结构与此处解释的“面向文档的设计”类似:

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

{
        "_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
    a变量文档作为每个文档的所有文档的
    $setUnion
    小时
  • $展开
    文档
  • $sort
    by
    orders
  • $limit
    顶部的
    10
    文档是我们需要的
代码:

var输入日期=新的ISODate(“2015-01-09T13:00:00Z”);
var-group={};
var集=[];

for(var i=0;我的策略就是这样的。for循环迭代次数太多了1次,但是这个概念本身是有效的。谢谢!
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"}}
])