百分位排名聚合

百分位排名聚合 #

percentile_ranks 百分比排名聚合估计低于或等于给定阈值的观测值百分比。这对于了解特定值在值分布中的相对位置很有用。 例如,您可以使用百分位排名聚合来学习交易金额 45 与数据集中其他交易值相比如何。百分位排名聚合返回一个值,如 82.3 ,这意味着 82.3% 的交易额低于或等于 45

参数说明 #

percentile_ranks 聚合采用以下参数。

参数必需/可选数据类型描述
field必需String用于计算百分位数的数值字段。
values必需Array of doubles用于计算百分位数的值。
keyed可选Boolean如果设置为 false ,则将结果作为数组返回。否则将结果作为 JSON 对象返回。默认值为 true 。
tdigest.compression可选Double控制 tdigest 算法的准确性和内存使用。参见使用 tdigest 进行精度调整。
hdr.number_of_significant_value_digits可选IntegerHDR 直方图的精度设置。参见 HDR 直方图。
missing可选Numeric当文档中目标字段缺失时使用的默认值。
script可选Object用于计算自定义值而不是使用字段的脚本。支持内联和存储脚本。

参考样例 #

首先,创建一个示例索引:

PUT /transaction_data
{
  "mappings": {
    "properties": {
      "amount": {
        "type": "double"
      }
    }
  }
}

添加示例数值以说明百分位数排名计算:

POST /transaction_data/_bulk
{ "index": {} }
{ "amount": 10 }
{ "index": {} }
{ "amount": 20 }
{ "index": {} }
{ "amount": 30 }
{ "index": {} }
{ "amount": 40 }
{ "index": {} }
{ "amount": 50 }
{ "index": {} }
{ "amount": 60 }
{ "index": {} }
{ "amount": 70 }

运行 percentile_ranks 聚合来计算某些值与整体分布的比较情况:

GET /transaction_data/_search
{
  "size": 0,
  "aggs": {
    "rank_check": {
      "percentile_ranks": {
        "field": "amount",
        "values": [25, 55]
      }
    }
  }
}

表明 28.6%的值小于或等于 25 ,71.4%的值小于或等于 55 :

{
  ...
  "hits": {
    "total": {
      "value": 7,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "rank_check": {
      "values": {
        "25.0": 28.57142857142857,
        "55.0": 71.42857142857143
      }
    }
  }
}

键值 #

可以通过将 keyed 参数设置为 false 来更改返回的聚合格式,从 JSON 对象更改为键值对列表:

GET /transaction_data/_search
{
  "size": 0,
  "aggs": {
    "rank_check": {
      "percentile_ranks": {
        "field": "amount",
        "values": [25, 55],
        "keyed": false
      }
    }
  }
}

返回内容包含一个数组而不是对象:

{
  ...
  "hits": {
    "total": {
      "value": 7,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "rank_check": {
      "values": [
        {
          "key": 25,
          "value": 28.57142857142857
        },
        {
          "key": 55,
          "value": 71.42857142857143
        }
      ]
    }
  }
}

使用 tdigest 进行精确度调整 #

默认情况下,百分位数排名使用 tdigest 算法计算。您可以通过指定 tdigest.compression 参数来控制准确性和内存使用之间的权衡。更高的值提供更好的准确性,但需要更多的内存。有关 tdigest 工作原理的更多信息,请参阅使用 tdigest 进行精度调整。 以下示例中将 tdigest.compression 设置为 200

GET /transaction_data/_search
{
  "size": 0,
  "aggs": {
    "rank_check": {
      "percentile_ranks": {
        "field": "amount",
        "values": [25, 55],
        "tdigest": {
          "compression": 200
        }
      }
    }
  }
}

HDR 直方图 #

作为 tdigest 的替代方案,您可以使用高动态范围(HDR)直方图算法,该算法更适合大量分组和快速处理。有关 HDR 直方图的工作原理的更多信息,请参阅 HDR 直方图。

如果您需要使用 HDR,则应:

  • 正在跨多个分组进行聚合。
  • 不需要在尾部的百分位数上要求极端的精确度。
  • 确保有足够的内存可用。

你应该避免 HDR,如果:

  • 尾部精度很重要。
  • 你正在分析偏斜或稀疏的数据分布。

以下示例中将 hdr.number_of_significant_value_digits 设置为 3 :

GET /transaction_data/_search
{
  "size": 0,
  "aggs": {
    "rank_check": {
      "percentile_ranks": {
        "field": "amount",
        "values": [25, 55],
        "hdr": {
          "number_of_significant_value_digits": 3
        }
      }
    }
  }
}

缺省值 #

如果某些文档缺少目标字段,你可以通过设置 missing 参数来指示查询使用备用值。以下示例确保没有 amount 字段的文档被视为其值为 0 ,并包含在百分位数计算中:

GET /transaction_data/_search
{
  "size": 0,
  "aggs": {
    "rank_check": {
      "percentile_ranks": {
        "field": "amount",
        "values": [25, 55],
        "missing": 0
      }
    }
  }
}

Script 脚本 #

除了指定字段,您还可以使用脚本动态计算值。这适用于需要应用转换的情况,例如货币转换或应用权重。

内联脚本 #

以下示例使用内联脚本计算转换后的值 3060 与增加 10%的 amount 字段值的百分位数排名:

GET /transaction_data/_search
{
  "size": 0,
  "aggs": {
    "rank_check": {
      "percentile_ranks": {
        "values": [30, 60],
        "script": {
          "source": "doc['amount'].value * 1.1"
        }
      }
    }
  }
}

存储脚本 #

要使用存储脚本,首先使用以下请求创建它:

POST _scripts/percentile_script
{
  "script": {
    "lang": "painless",
    "source": "doc[params.field].value * params.multiplier"
  }
}

然后用 percentile_ranks 聚合中的存储脚本:

GET /transaction_data/_search
{
  "size": 0,
  "aggs": {
    "rank_check": {
      "percentile_ranks": {
        "values": [30, 60],
        "script": {
          "id": "percentile_script",
          "params": {
            "field": "amount",
            "multiplier": 1.1
          }
        }
      }
    }
  }
}