均值聚合

一种单值指标聚合,计算从聚合的文档中提取出来的数值的平均值的。这些数值可以从文档中某些特定的数值字段中提取出来,也可以使用给定的脚本生成。

假设数据由代表学生考试成绩的文档(0-100)组成,我们可以这样计算学生的平均成绩:

curl -X POST http://host_ip:host_port/exams/_search?pretty
-H 'content-type:application/json'
-d '{
    "size": 0,
    "aggs":{
        "avg_grade": {
            "avg": {
                "field": "grade"
            }
        }
    }
}'

上面的聚合会计算所有文档的平均成绩,聚合的类型是avg, "field"定义了文档中被用于计算平均值的数值字段,上面的请求会返回:

{
    ...
    "aggregations": {
        "avg_grade": {
            "value": 75.0
        }
    }
}

聚合的名字(avg_grade)也可以作为从返回的响应中提取出聚合结果的key。

脚本

基于脚本可以计算平均成绩:

curl -X POST http://host_ip:host_port/exams/_search?pretty
-H 'content-type:application/json'
-d '{
    "size": 0,
    "aggs":{
        "avg_grade": {
            "avg": {
                "script": {
                    "source": "doc.grade.value"
                }
            }
        }
    }
}'

上面这种方式将会把script参数解释为内联脚本(无痛的脚本语言,不需要脚本参数)。如果要使用缓存的脚本,使用下面的方式(可以参考上上篇博文:params允许把脚本中所有动态的表达式定义为参数,这种方式可以让脚本在调用间保持为静态的(这会确保使用的是ES中缓存的编译过的脚本)):

curl -X POST http://host_ip:host_port/exams/_search?pretty
-H 'content-type:application/json'
-d '{
    "size": 0,
    "aggs":{
        "avg_grade": {
            "avg": {
                "script": {
                    "id": "my_script",
                    "params": {
                        "field": "grade"
                    }
                }
            }
        }
    }
}'

值脚本

有可能exam的层次比学生的水平要高,我们需要进行成绩校正,我们可以使用值脚本来得到新的平均值(也可以参考上上篇博文:当聚合中既配置了field又设置了script时,script就会被当成value script。普通的script会基于文档的层次评估(即这个脚本可以获得与文档相关的所有数据),value script是在值的层次上评估的,在这种模式下,value是从配置的field字段中提取出来的,script则被用来对这些值进行transform):

curl -X POST http://host_ip:host_port/exams/_search?pretty
-H 'content-type:application/json'
-d '{
    "size": 0,
    "aggs":{
        "avg_corrected_grade": {
            "avg": {
                "field": "grade",
                "script": {
                    "lang": "painless",
                    "source": "_value*params.correction",
                    "params": {
                        "correction": 1.2
                    }
                }
            }
        }
    }
}'

 丢失的值

missing参数定义了某个字段缺失值的文档应该被如何处理。默认的,这些文档会被忽略,但我们也可以把这些文档当作它们这个字段有某个值来对待。

curl -X POST http://host_ip:host_port/exams/_search?pretty
-H 'content-type:application/json'
-d '{
    "size": 0,
    "aggs":{
        "avg_grade": {
            "avg": {
                "field": "grade",
                "missing": 10
            }
        }
    }
}'

上面的请求意味着grade缺失的文档会跟grade=10的文档落入相同的bucket中。