Elastic Search聚合之bucket script

在前文Elastic Search 聚合笔记中已经介绍了Elastic Search聚合的基本用法,但这些常规的统计有的时候会不够用,Elastic Search提供了很多其它的聚合方式来补充,本文这里就介绍下其中很是灵活实用的bucket script的基本用法。html

例如,咱们在进行统计分析的时候,除了统计数量外,每每还会要求统计出知足某条件的数量占总数的比例,须要通过以下三个步骤。java

  1. 求出当前文档数量
  2. 求出知足条件的文档的数量
  3. 计算两个数量的百分比

前两个数据还比较好说,只须要加一个filter bucket便可,例如,咱们想求出某bucket下的全部男性数量:elasticsearch

"aggs": {
  "
男性
": {
    "filter": { "term": { "
性别""
" } }
  }
ide

返回值为 ui

{
    "key""true",
    "doc_count"497,
    "
男性": { "doc_count"208   },
    "
男性比例": { "value"41.0 }
}
spa

可看到,自己就返回了每一个聚合的数量。难点在第3步,须要在前面两步的基础上再进行运算,这个就是比较典型的管道聚合了,因为咱们当前只是一个简单的运算,使用bucket script注入一些脚本的功能是很容易实现的,它的基本格式以下:htm

{
    "bucket_script": {
        "buckets_path": {
            "my_var1""the_sum"
            "my_var2""the_value_count"
        },
        "script""params.my_var1 / params.my_var2"
    }
}
blog

主要有两个参数 ip

  • bucket_path:指定相关上下文变量的查询路径,至关于定义变量和变量查询路径。其语法规则可参看 bucket_path语法规则,并不复杂,通常状况下也能猜出个大体。
  • script: 脚本内容,支持好几种语法,默认的相似java,具体可参看官方文档: Scripting

有了上述基础后,就能够构建bucket script了,本文示例以下 ci

"aggs": {
  "
男性": {
    "filter": { "term": { "
性别""" } }
  },
  "
男性比例": {
    "bucket_script": {
      "buckets_path": {
        "p1""
男性._count",
        "p2""_count"
      },
      "script""(int)(100 * params.p1 / params.p2)"
    }
  }
}

这里用了"_count"这个特殊的路径,它表明文档的数量,这个在官方文档中也有介绍:special path

而后,咱们就获得想要的结果了。

{
    "key""true",
    "doc_count"497,
    "
男性": { "doc_count"208   },
    "
男性比例": { "value"41.0 }
}

自己仍是比较简单的,不过这个有个限制,那就是不能用在顶层聚合中,不然报错。若是没有上级聚合,能够用一些规避的方式,例如,构造一个到全部数据的聚合做为顶层聚合。

"aggs": {
  "top": {
    "terms": { "script""true" },
    //... ...
  }}