汇总时间序列数据

时间:2017-02-16 22:11:54

标签: node.js mongodb mongoose mapreduce

我使用mongoDB和mongoose来存储指标数据。它存储为一个文档,用于引用其存储的项目和度量标准类型的度量标准数组。

此架构如下所示:

exports.metricReportSchema = new Schema({
    metrics: [{
        metric: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'metricSchema',
            required: true
        },
        value: {
            type: String,
            required: true
        }
    }],
    project: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'projectSchema',
        required: true
    },
    reportDate: Date
});

实际文档如下所示:

db.metricreports.findOne() {
    "_id" : ObjectId("58a60e8459dd3d12ef8c5d51"),
    "reportDate" : ISODate("2017-02-16T20:41:40.657Z"),
    "project" : ObjectId("58a20f5f04ef5789d3ef8faa"),
    "metrics" : [
        {
            "metric" : ObjectId("58a20f5f04ef5789d3ef8fb7"),
            "value" : "781",
            "_id" : ObjectId("58a60e8459dd3d12ef8c5d52")
        }, {
            "metric" : ObjectId("58a21106fc2aef8a10ded196"),
            "value" : "566",
            "_id" : ObjectId("58a60e8459dd3d12ef8c5d53")
        }, {
            "metric" : ObjectId("58a2141bded78e8ad8384f97"),
            "value" : "501",
            "_id" : ObjectId("58a60e8459dd3d12ef8c5d54")
        }, {
            "metric" : ObjectId("58a2141bded78e8ad8384f94"),
            "value" : "44",
            "_id" : ObjectId("58a60e8459dd3d12ef8c5d55")
        }, {
            "metric" : ObjectId("58a2141bded78e8ad8384f93"),
            "value" : "645",
            "_id" : ObjectId("58a60e8459dd3d12ef8c5d56")
        }
    ],
    "__v" : 0
}

随着时间的推移,有多种此类文档可存储多个指标的数据片段。选择和显示多个项目的指标静态报告非常方便。

现在,当我尝试为项目的单个指标构建时间序列报告时,这变得有点复杂。

基本上,我需要做的是扫描多个metricReport文档,并随时间从所有可用报告中提取单个指标的数据。假设我有10个metricReports,每个都包含10个不同指标的数据,我只想提取一个,这可能看起来像这样:

{
    "_id": "...",
    "project": "...",
    "metric": "...",
    "data": {
        "2016-02-02": "22",
        "2016-02-03": "453",
        ...
    }
}

我无法通过开箱即用的mongoDB查询和过滤功能找到方法,并且想要寻求建议:

  1. 我在单个文档中存储多个指标的方法是否合理?我会更好地将指标作为单独的文档保存,然后以某种方式“合并”它们吗?
  2. 有没有办法实现我需要的东西而不用nodejs做这个(我假设这不会是非常快的事情 - 抓住文件然后迭代它们以创建一个新的结构并推出它)?< / LI>
  3. 有更好的方法吗?虚拟模型或猫鼬的东西可以帮助?我知道mongoDB可能不是时间序列数据的正确选择,但它不是功能的唯一部分,mongoDB / mongoose组合似乎很好地服务于其他目的,我不想在中途改变技术。 / LI>

1 个答案:

答案 0 :(得分:0)

  1. 是的,但请记住,文档的大小有限(16 MB IIRC),因此,如果您的数据无限制,则此结构将无效,因为您的“指标”数组将超过该数据。

  2. 最终是的,即使你找不到合适的过滤器查询,Mongo也有MapReduce可以让你做你想做的事情,虽然这并不容易。我会使用Node。

  3. 这里没有银弹。如果您需要聚合数据并将其存储为任意JSON(即由应用程序使用),Mongo非常出色,而且在进行复杂的数据连接/视图时效果不是很好。应用程序级别的任何联接都会很慢。如果您想要表现,则必须将报告汇总到单个文档中,并保存&amp;为他们服务。如果您有实时数据,这将更加困难,因为您需要处理更新。