【问题标题】:Use aggregation framework to get peaks from a pre-aggregated dataset使用聚合框架从预先聚合的数据集中获取峰值
【发布时间】:2013-01-30 08:13:53
【问题描述】:

我有一些指标集合,它们预先聚合到小时和分钟集合中,如下所示:

"_id" : "12345CHA-2RU020130104",
"metadata" : {
                "adaptor_id" : "CHA-2RU",
                "processor_id" : NumberLong(0),
                "date" : ISODate("2013-01-04T00:00:00Z"),
                "processor_type" : "CHP",
                "array_serial" : NumberLong(12345)
        },
"hour" : {
            "11" : 4.6665907,
            "21" : 5.9431519999999995,
            "7" : 0.6405864,
            "17" : 4.712744,
        ---etc---
    },  
"minute" : {
            "11" : {
                "33" : 4.689972,
                "32" : 4.7190895,
            ---etc---                        
                },
            "3" : {
                "45" : 5.6883,
                "59" : 4.792,
            ---etc---
            }

分钟集合每个小时都有一个子文档,其中每个分钟都有一个条目,其中包含该分钟的度量值。

我的问题是关于聚合框架的,如果我想找到指标高于某个高水位线的所有分钟数,我应该如何处理这个集合?调查聚合框架显示了一个 $unwind 函数,但这似乎只适用于数组..

map/reduce 功能会更适合这个吗?有了它,我可以简单地发出高于高水位线的任何条目并计算它们。

【问题讨论】:

  • $project 可能有助于将您的对象转换为可以在下游聚合的东西。不将此作为答案提交,因为它不完全适合您正在做的事情,但我在这里探索了几种不同的临时聚合技术:devsmash.com/blog/…
  • @Chris:我认为您为此受困于 MapReduce。聚合运算符没有任何将“键”用作“值”的机制。
  • 我不会说我坚持下去,这还不错,我只是想知道聚合框架是否有性能改进。

标签: mongodb mongodb-query


【解决方案1】:

您可以使用遍历对象属性的 reduce 函数构建一个“键”数组。

 reduce: function(obj,prev)
 {
    for(var key in obj.minute) {
        prev.results.push( { hour:key, minutes: obj.minute[key]});
    }
 }

会给你类似的东西

  {
          "results" : [
                  {
                          "hour" : "11",
                          "minutes" : {
                                  "33" : 4.689972,
                                  "32" : 4.7190895
                          }
                  },
                  {
                          "hour" : "3",
                          "minutes" : {
                                  "45" : 5.6883,
                                  "59" : 4.792
                          }
                  }
          ]
  }

我刚刚使用 group() 进行了快速测试 - 您需要更复杂的东西来迭代子子文档(分钟),但希望为您指明正确的方向。

db.yourcoll.group( {
initial: { results: [] }, reduce: function(obj,prev) { for(var key in obj.minute) { prev.results.push( { hour:key, minutes: obj.minute[key]}); } } } );

在终结器中,您可以再次重塑数据。它不会很漂亮,将分钟和小时数据保存为数组而不是文档的元素可能更容易。

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2012-10-20
    • 2023-03-31
    • 2021-06-15
    • 1970-01-01
    • 2015-10-31
    • 2015-03-20
    • 2021-03-21
    • 1970-01-01
    • 2020-03-13
    相关资源
    最近更新 更多