Elasticsearch 指标聚合查询

659 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Elasticsearch 聚合查询

聚合是一种基于查询条件对数据进行分桶、计算的方法。

聚合可以嵌套,由此可以组合复杂的操作(Bucketing 聚合可以包含 sub-aggregation)。

聚合的三种分类:

  • Metric(指标聚合)
    • 对文档进行权值计算,输出结果既是权值。
    • 基于特定字段(field)或脚本值(generated using scripts)计算。
  • Bucketing(分桶聚合):
    • 对文档进行分组操作,把满足相关特性的文档分到一个桶里,即桶分。输出结果是包含多个文档的桶。
    • 基于一个关键字(field、script),以及一些桶分(分组)的判断条件进行聚合,符合条件的会分到对应的组(fall in)。
  • Pipeline(管道聚合):
    • 对其它聚合操作的输出以及关联指标进行聚合。
    • 此类聚合的作用对象大多是桶,而不是文档,是一种后期对每一个分桶的一些计算操作。

指标聚合

sum 聚合(single-value)

sum 是一个求累加值的聚合,其作用与关系型数据库中相同。

参数:

  • field:用于计算的字段;
  • script:由脚本生成用来计算的 value;
  • missing:文档缺失字段时的默认值。
GET /lib4/items/_search
{
    "size": 0, # 表示查询多少条文档,聚合只需就和结果,输出文档可以设置为0"aggs": {
        "price_of_sum": { # 自行取名作为结果集
            "sum": {
                "field": "price"
            }
        }
    }
}

min 聚合(single)

min是一个求最小值的聚合,其作用与关系型数据库中相同。

参数:

  • field:用于计算的字段;
  • script:由脚本生成用来计算的 value;
  • missing:文档缺失字段时的默认值。
GET /lib4/items/_search
{
    "size": 0,
    "aggs": {
        "price_of_min": {
            "min": {
                "field": "price"
            }
        }
    }
}

//最小值,script
{
    "size", 0
    "aggs" : {
        "price_of_min_script" : {
            "min" : {
                "script" : {                //script 计算 value
                    "file": "my_script",
                    "params": {
                        "field": "price"
                     }
            	}
            }
    	}
    }
}

max 聚合(single)

max是一个求最大值聚合,其作用与关系型数据库中相同。

参数:

  • field:用于计算的字段;
  • script:由脚本生成用来计算的 value;
  • missing:文档缺失字段时的默认值。
GET /lib4/items/_search
{
    "size": 0,
    "aggs": {
        "price_of_max": {
            "max": {
                "field": "price"
            }
        }
    }
}

avg 聚合(single-value numeric metrics)

avg是一个求平均值的聚合,其作用与关系型数据库中相同。

参数:

  • field:用于计算的字段;
  • script:由脚本生成用来计算的 value;
  • missing:文档缺失字段时的默认值。
GET /lib4/items/_search
{
    "size": 0,
    "aggs": {
        "price_of_avg": {
            "avg": {
                "field": "price"
            }
        }
    }
}

cardinality 聚合(single-value)

cardinality是一个求基数的聚合,其作用与关系型数据库中相同。

参数:

  • field:用于计算的字段;
  • script:由脚本生成用来计算的 value;
  • precision_threshold:精度阈值,用于处理准确度问题;
  • missing:文档缺失字段时的默认值。
GET /lib4/items/_search
{
    "size": 0,
    "aggs": {
        "price_of_cardi": {
            "cardinality": { # 其实相当于该字段互不相同的值有多少类,输出的是种类数
                "field": "price"
            }
        }
    }
}

stats 聚合(multi-value)

统计聚合,基于文档的某个值,计算出一些统计信息(min、max、sum、count、avg)。

参数:

  • field:用于计算的字段;
  • script:由脚本生成用来计算的 value;
  • missing:文档缺失字段时的默认值。
{
    "aggs" : {
        "grades_stats" : { 
        	"stats" : { 
        		"field" : "grade" 
        	} 
        }
    }
}

//输出
{
    ...
    "aggregations": {
        "grades_stats": {
            "count": 6,
            "min": 60,
            "max": 98,
            "avg": 78.5,
            "sum": 471
        }
    }
}

Extended stats 聚合(multi-value)

扩展统计聚合,基于文档的某个值,计算出一些统计信息(比普通的stats聚合多了sum_of_squares、variance、std_deviation、std_deviation_bounds)。

参数:

  • field:用于计算的字段;
  • script:由脚本生成用来计算的 value;
  • missing:文档缺失字段时的默认值;
  • sigma:标准差界限。
{
    ...
    "aggregations": {
        "grade_stats": {
           "count": 9,
           "min": 72,
           "max": 99,
           "avg": 86,
           "sum": 774,
           //输出比 stats 聚合多了一些值
           "sum_of_squares": 67028,
           "variance": 51.55555555555556,
           "std_deviation": 7.180219742846005,
           "std_deviation_bounds": {
               "upper": 100.36043948569201,
               "lower": 71.63956051430799
            }
        }
    }
}

Geo Bounds 聚合

地理边界聚合,基于文档的某个字段(geo-point类型字段),计算出该字段所有地理坐标点的边界(左上角/右下角坐标点)。

参数:

  • field:用于计算的字段;
  • wrap_longitude:是否允许地理边界与国际日界线存在重叠。
{
    "query" : {
        "match" : { "business_type" : "shop" }
    },
    "aggs" : {
        "viewport" : {
            "geo_bounds" : {
                "field" : "location", 
                "wrap_longitude" : true 
            }
        }
    }
}

//输出
{
    ...
    "aggregations": {
        "viewport": {
            "bounds": {
                "top_left": {                    //左上角经纬度
                    "lat": 80.45,
                    "lon": -160.22
                },
                "bottom_right": {               //右下角经纬度
                    "lat": 40.65,
                    "lon": 42.57
                }
            }
        }
    }
}

Geo Centroid 聚合

地理重心聚合,基于文档的某个字段(geo-point类型字段),计算所有坐标的加权重心。

参数:

  • field:用于计算的字段(geo-point类型)。
{
    "query" : {
        "match" : { "crime" : "burglary" }
    },
    "aggs" : {
        "centroid" : {
            "geo_centroid" : {
                "field" : "location" 
            }
        }
    }
}

//输出
{
    ...
    "aggregations": {
        "centroid": {
            "location": {      //重心经纬度
                "lat": 80.45,
                "lon": -160.22
            }
        }
    }
}

Percentiles 聚合(multi-value)

百分百聚合,基于聚合文档中某个数值类型的值,求这些值中。

参数:

  • field:用于计算的字段;
  • script:由脚本生成用来计算的 value;
  • missing:文档缺省字段时的默认。

Script Metric 聚合

基于脚本的权值聚合,用脚本来计算出一个权值。

参数:

  • init_script:用于计算的字段;
  • map_script:由脚本生成用来计算的 value;
  • combine_script:文档缺省字段时的默认值;
  • reduce_script:
{
    "query" : {
        "match_all" : {}
    },
    "aggs": {
        "profit": {
            "scripted_metric": {
                "init_script" : "_agg['transactions'] = []",
                "map_script" : "if (doc['type'].value == \"sale\") { _agg.transactions.add(doc['amount'].value) } else { _agg.transactions.add(-1 * doc['amount'].value) }", 
                "combine_script" : "profit = 0; for (t in _agg.transactions) { profit += t }; return profit",
                "reduce_script" : "profit = 0; for (a in _aggs) { profit += a }; return profit"
            }
        }
    }
}

Top hits 聚合

最高匹配权值聚合,跟踪聚合中相关性最高的文档。

该聚合一般用做 sub-aggregation,以此来聚合每个桶中的最高匹配的文档。

参数:

  • from:最匹配的结果中的文档个数偏移;
  • size:top matching hits 返回的最大文档个数(default 3);
  • sort:最匹配的文档的排序方式。
{
    "aggs": {
        "top-tags": {
            "terms": {
                "field": "tags",
                "size": 3
            },
            "aggs": {
                "top_tag_hits": {
                    "top_hits": {                  //用 tags 字段分组,每个 tag(即一个分组)只显示最后一个问题,并且只在 _source 中保留 title 字段
                        "sort": [
                            {
                                "last_activity_date": {
                                    "order": "desc"
                                }
                            }
                        ],
                        "_source": {
                            "include": [
                                "title"
                            ]
                        },
                        "size" : 1
                    }
                }
            }
        }
    }
}

//输出
"top_tags_hits": {
     "hits": {
          "total": 25365,
          "max_score": 1,
          "hits": [
              {
                 "_index": "stack",
                 "_type": "question",
                 "_id": "602679",
                 "_score": 1,
                 "_source": {
                      "title": "Windows port opening"
                 },
                 "sort": [
                  ]
               }
           ]
     }
}

Value Count 聚合(single-value)

值计数聚合,计算聚合文档中某个值的个数。

用于计数的值可以是特定的数值型字段,也可以通过脚本计算而来。

该聚合一般域其它 single-value 聚合联合使用,比如在计算一个字段的平均值的时候,可能还会关注这个平均值是由多少个值计算而来。

参数:

  • field:用于计算的字段
  • script:由脚本生成用来计算的 value
{
    "aggs" : {
        "grades_count" : { 
        	"value_count" : { 
        		"field" : "grade" 
        	} 
        }    //计算 grade 字段共有多少个值,和 cardinality 聚合不同的
    }
}