【问题标题】:MongoDB, TimeSeries and Aggregation FrameworkMongoDB、时间序列和聚合框架
【发布时间】:2015-10-24 20:54:39
【问题描述】:

所以,我正在使用 MongoDB 处理这个时间序列数据并发现: http://blog.mongodb.org/post/65517193370/schema-design-for-time-series-data-in-mongodb

它说这种结构不会利用“文档模型的表达性”:

{
  timestamp: ISODate("2013-10-10T23:06:37.000Z"),
  type: ”memory_used”,
  value: 1000000
}

他们建议像这样(分钟/秒):

{
  timestamp_hour: ISODate("2013-10-10T23:00:00.000Z"),
  type: “memory_used”,
  values: {
    0: { 0: 999999, 1: 999999, …, 59: 1000000 },
    1: { 0: 2000000, 1: 2000000, …, 59: 1000000 },
    …,
  }
}

所以我决定像这样(年/月)对我的数据进行建模:

{
  "unity_of_measure": "MWh",
  "region": "North",
  "consumption": {
    2014: {1: 2568.652, 2: 2614.621, 3: 2711.012 } ,
    2015: {1: 2751.234, 2: 2752.231, 3: 2752.215 } ,
    …
  }
}

我不知道我是不是搞错了,但是聚合框架似乎无法获得最大/最小/总和/平均值,例如,使用这种建模。

所以我把我的模型改成了这样:

{
  "unity_of_measure": "MWh",
  "region": "North",
  "consumption": [
    { "year": 2014,
      "month": 1,
      "value": 2568.652
    },
    { "year": 2014,
      "month": 2,
      "value": 2614.621
    }
    ...
  ]
}

但现在我发现自己没有利用“文档模型的表达性”。所以我真的很困惑。

有没有什么方法可以使用聚合框架和 mongo 的博客建议的建模?这里的想法是不使用 map reduce 或类似的东西。

如果不可能,第二次建模在性能方面有多糟糕?

抱歉这个问题太长了,我希望我能在这里贴一个土豆。

提前致谢。

【问题讨论】:

  • 不要太拘泥于“文档模型的表达性”——我认为这是文章中的不幸措辞。他们提出的模式只是一种有助于满足设计目标的选择。它因其他设计目标而失败,如下所述。六年前,我在 Oracle 中编写了完全相同的策略,而 mongo 设计不再具有表现力——它们在功能上是等效的,并且具有相似的表现力。
  • 你好史蒂夫塔弗。非常感谢您与我和社区分享的所有信息和经验,它确实帮助我考虑了很多事情!如果你知道一些文章或任何讨论这个话题的东西,你能和我分享吗?再次感谢!
  • 哪个主题?大规模指标收集或列表计算?

标签: mongodb time-series data-modeling aggregation-framework


【解决方案1】:

我认为您错过了文章中的一些重要内容 -> 他们会在每次更新时更新汇总统计字段,以便他们可以计算应用程序中的平均值。他们在时间序列数据上使用 $set,在 num_samples 和 total_samples 上使用 $inc,因为文档字段更新非常便宜并且允许它们达到它们所处的规模。时间序列数据用于显示 - 不用于 mongo 中的计算。

聚合和映射函数对列表进行操作 - 您的第一个示例没有 - 它有一个包含时间序列数据的子文档。您可以在聚合管道中进行平均,但在应用程序代码中这样做会非常难看且更简单。

如果您想在 mongo 中进行计算,则必须将数据组织在某种列表中,例如您的第二个示例。

使用第二个模式作为提示,您可以按照以下方式进行计算。打开一个 mongo shell,使用一个像 test 一样的临时数据库,然后将其粘贴进去看看它是否工作。

// clean up from previous run
db.timeSeries2.drop();

// Given data like
db.timeSeries2.insert(
    {
      "unit_of_measure": "MWh",
      "region": "North",
      "consumption": [
        {
          "year": 2014,
          "month": 1,
          "value": 50
        },
        {
          "year": 2014,
          "month": 2,
          "value": 100
        },
        {
          "year": 2014,
          "month": 3,
          "value": 150
        },
        {
          "year": 2015,
          "month": 1,
          "value": 500
        },
        {
          "year": 2015,
          "month": 2,
          "value": 1000
        },
        {
          "year": 2015,
          "month": 3,
          "value": 1500
        }
      ]
    }
);

// aggregation to provide min/max/sum/average
db.timeSeries2.aggregate([
  {$match: {region: 'North', unit_of_measure: 'MWh'}},
  {$unwind: '$consumption'},
  {$match: {'consumption.year': 2014}},
  {
    $group: {
      _id: 'summary',
      avg: {$avg: '$consumption.value'},
      sum: {$sum: '$consumption.value'},
      min: {$min: '$consumption.value'},
      max: {$max: '$consumption.value'}
    }
  }
])

生产

{
  "result": [
    {
      "_id": "summary",
      "avg": 100,
      "sum": 300,
      "min": 50,
      "max": 150
    }
  ],
  "ok": 1
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    相关资源
    最近更新 更多