mongodb - 如何计算百分位数

时间:2013-08-28 09:49:11

标签: mongodb mongodb-query

我有一个如下所示的访问日志,它们存储在mongodb实例中:

Time                          Service                 Latency
[27/08/2013:11:19:22 +0000]    "POST Service A HTTP/1.1"    403
[27/08/2013:11:19:24 +0000]    "POST Service B HTTP/1.1"    1022 
[27/08/2013:11:22:10 +0000]    "POST Service A HTTP/1.1"    455 

在Oracle中是否存在类似PERCENTILE_DISC的分析函数来计算百分位数?我想在一段时间内计算潜伏期百分位数。

2 个答案:

答案 0 :(得分:9)

似乎仍然没有本地计算百分位数的方法,但通过组合一些聚合运算符,您可以得到相同的结果。

db.items.aggregate([
        {'$group': {
            '_id': {
                'league': '$league',
                'base': '$base',
                'type': '$type'
            },
            'value': {'$push': '$chaosequiv'}
        }},
        {'$unwind': '$value'},
        {'$sort': {'value': 1}},
        {'$group': {'_id': '$_id', 'value': {'$push': '$value'}}},
        {'$project': {
            '_id': 1,
            'value': {'$arrayElemAt': ['$value', {'$floor': {'$multiply': [0.25, {'$size': '$value'}]}}]}
        }}
    ], allowDiskUse=True)

注意我在pymongo中编写了我的原始代码,以解决需要在第一组中的3个字段进行分组的问题,因此这可能比单个字段所需的更复杂。我会写一个特定于这个问题的解决方案,但我认为没有足够的具体信息。

答案 1 :(得分:1)

Mongo 4.4开始,$group阶段有了一个新的聚合运算符$accumulator,允许通过javascript用户定义函数对文档进行分组时进行自定义累积。

因此,为了找到第20个百分位数:

// { "a" : 25, "b" : 12 }
// { "a" : 89, "b" : 73 }
// { "a" : 25, "b" : 7  }
// { "a" : 25, "b" : 17 }
// { "a" : 89, "b" : 14 }
// { "a" : 89, "b" : 17 }
// { "a" : 25, "b" : 24 }
// { "a" : 25, "b" : 15 }
// { "a" : 25, "b" : 22 }
// { "a" : 25, "b" : 94 }
db.collection.aggregate([
  { $group: {
    _id: "$a",
    percentile: {
      $accumulator: {
        accumulateArgs: ["$b"],
        init: function() { return []; },
        accumulate: function(bs, b) { return bs.concat(b); },
        merge: function(bs1, bs2) { return bs1.concat(bs2); },
        finalize: function(bs) {
          bs.sort(function(a, b) { return a - b });
          return bs[Math.floor(bs.length*.2) + 1];
        },
        lang: "js"
      }
    }
  }}
])
// { "_id" : 89, "percentile" : 17 }
// { "_id" : 25, "percentile" : 15 }

累加器:

  • 累积在baccumulateArgs)字段上
  • 被初始化为空数组(init
  • 在一个数组(baccumulate)中累积merge个项目
  • 最后对b个项目(finalize)进行百分位计算