赞
踩
聚集查询(Aggregation)提供了针对多条文档的统计运算功能,它不是针对文档本身内容的检索,而是要将它们聚合到一起运算某些方面的特征值。
聚集查询与SQL语言中的聚集函数非常像,聚集函数在Elasticsearch中相当于是聚集查询的一种聚集类型。比如在SQL中的avg函数用于求字段平均值,而在Elasticsearch中要实现相同的功能可以使用avg聚集类型。
聚集查询也是通过_search接口执行,只是在执行聚集查询时使用的参数是aggregations或aggs。所以_search接口可以执行两种类型的查询:
这两种查询方式还可以放在一起使用, 执行逻辑是先通过DSL检索满足查询条件的文档,然后再使用聚集查询对DSL检索结果做聚集运算。
聚集查询有着比较规整的请求结构,具体格式如下:
"aggregations/aggs" : {
"<聚集名称>":{
"<聚集类型>":{
<聚集体>
}
………
[,"aggregations/aggs" : ( [ <子聚集>]+ ) ]
}
[,"<聚集名称>”: (...) ]*
}
aggregations和aggs都是_search的参数,其中aggs是agregations的简写。每一个聚集查询都需要定义一个聚集名称,并归属于种聚集类型。聚集名称是用户自定义的, 而聚集类型则是由Elasticsearch预先定义好。聚集名称会在返回结果中标识聚集结果,而聚集类型则决定了聚集将如何运算。比如前面提到的avg就是一种聚集类型。这里要特别强调的是,聚集中可以再包含子聚集。子聚集位于父聚集的名称中,与聚集类型同级,所以子聚集的运算都是在父聚集的环境中运算。
Eaticsarch对子聚集的深度没有限制,所以理论上说可以包含无限深度的子聚集。
聚集类型总体上被分为四种大类型:
指标聚集是根据文档中某一字段做聚集运算,比如计算所有产品销量总和、平均值等等。指标聚集的结果可能是单个值,这种指标聚集称为单值指标聚集;也可能是多个值,称为多值指标聚集。
平均值聚集是根据文档中数值类型字段计算平均值的聚集查询,包括avg聚集和weighted_avg聚集两种类型。
avg聚集直接取字段值后计算平均值,而weighted_avg聚集则会在计算平均值时添加不同的权重。
avg聚集计算平均值,例如计算航班的平均延误时间:
POST kibana_sample_data_flights/_search?filter_path=aggregations
{
"aggs": {
"avg_aggs": {
"avg": {
"field": "FlightDelayMin"
}
}
}
}
使用了请求参数fiter_path将返回结果的其他字段过滤掉了,否则查询的结果中将包含kibana_sample_data_flights索引中的文档。加了filter_path之后返果为:
{
"aggregations" : {
"avg_aggs" : {
"value" : 47.33517114633586
}
}
}
在返回结果中,aggregations是关键字,代表这是聚集查询的结果。其中的delay_avg则是在聚集查询中定义的聚集名称,value是聚集运算的结果。在示例中运算航班延误时间时会将所有文档都包含进来做计算,如果只想其中一部分文档参与运算则可以使用query参数以DSL的形式定义查询条件。
例如只计算了飞往中国的航班平均延误时间:
POST kibana_sample_data_flights/_search?filter_path=aggregations
{
"query": {
"match": {
"DestCountry": "CN"
}
},
"aggs": {
"avg_aggs": {
"avg": {
"field": "FlightDelayMin"
}
}
}
}
输出结果:
{
"aggregations" : {
"avg_aggs" : {
"value" : 44.73996350364963
}
}
}
在示例中请求_search接口时,同时使用了query与aggs参数。在执行检索时会先通过query条件过滤文档,然后再在符合条件的文档中运算平均值聚集。
weighted_avg无非就是根据某些条件对进行聚集的数据进行加权运算,和avg聚集没有本质差别。
POST kibana_sample_data_flights/_search?filter_path=aggregations
{
"query": {
"match": {
"DestCountry": "CN"
}
},
"aggs": {
"avg_aggs": {
"weighted_avg": {
"value": {
"field": "FlightDelayMin"
},
"weight": {
"field": "DistanceKilometers"
}
}
}
}
}
输出结果:
{
"aggregations" : {
"avg_aggs" : {
"value" : 42.29622477052496
}
}
}
计数聚集用于统计字段值的数量,类似于SQL中的count。
POST kibana_sample_data_flights/_search?filter_path=aggregations
{
"aggs": {
"count": {
"cardinality": {
"field": "DestCountry"
}
},
"distinct_count": {
"value_count": {
"field": "DestCountry"
}
}
}
}
输出结果:
{
"aggregations" : {
"count" : {
"value" : 32
},
"distinct_count" : {
"value" : 13059
}
}
}
value_count聚集用于统计字段中值的总数,而cardinality用于统计不重复值的总数。
cardinality聚集的算法使用极小内存实现统计结果的基本准确。所以cardinality在数据量极大的情况下是不能保证完全准确的。
极值聚集是在文档中提取某一字段最大值或最小值的聚集,包括max聚集和min聚集。
例如:
POST kibana_sample_data_flights/_search?filter_path=aggregations
{
"aggs": {
"min_price": {
"min": {
"field": "AvgTicketPrice"
}
},
"max_price": {
"max": {
"field": "AvgTicketPrice"
}
}
}
}
输出结果:
{
"aggregations" : {
"max_price" : {
"value" : 1199.72900390625
},
"min_price" : {
"value" : 100.0205307006836
}
}
}
和聚集就是求某个字段的和,类似于SQL中的sum。
POST kibana_sample_data_flights/_search?filter_path=aggregations
{
"query": {
"match": {
"DestCountry": "CN"
}
},
"aggs": {
"sum_aggs": {
"sum": {
"field": "FlightDelayMin"
}
}
}
}
输出结果:
{
"aggregations" : {
"sum_aggs" : {
"value" : 49035.0
}
}
}
统计聚集是一个多值指标聚集,也就是返回结果中会包含多个值,都是一些与统计相关的数据。统计聚集包含stats聚集和extended_stats聚集两种,前者返回的统计数据是一些比较基本的数值,而后者则包含一些比较专业的统计数值。
stats聚集返回结果中包括字段的最小值(min)、最大值(max)、总和(sum)、计数(count) 及平均值(avg) 五项内容。
例如,对机票价格做统计:
POST kibana_sample_data_flights/_search?filter_path=aggregations
{
"aggs": {
"price_stats": {
"stats": {
"field": "AvgTicketPrice"
}
}
}
}
输出结果:
{
"aggregations" : {
"price_stats" : {
"count" : 13059,
"min" : 100.0205307006836,
"max" : 1199.72900390625,
"avg" : 628.2536888148849,
"sum" : 8204364.922233582
}
}
}
extended_stats聚集增加了几项统计数据,这包括平方和、方差、标准方差和标准方差偏移量。从使用的角度来看,extended_stats聚集与stats聚集完全相同,只是聚集类型不同。
POST kibana_sample_data_flights/_search?filter_path=aggregations
{
"aggs": {
"price_stats": {
"extended_stats": {
"field": "AvgTicketPrice"
}
}
}
}
输出结果:
{
"aggregations" : {
"price_stats" : {
"count" : 13059,
"min" : 100.0205307006836,
"max" : 1199.72900390625,
"avg" : 628.2536888148849,
"sum" : 8204364.922233582,
"sum_of_squares" : 6.081113366492191E9,
"variance" : 70961.85310632498,
"std_deviation" : 266.38666090163935,
"std_deviation_bounds" : {
"upper" : 1161.0270106181636,
"lower" : 95.48036701160618
}
}
}
}
百分位聚集根据文档字段值统计字段值按百分比的分布情况,包括pecrentiles聚集和percentile_ranks两种。前者统计的是百分比与值的对应关系,而后者正好相反统计值与百分比的对应关系。
POST kibana_sample_data_flights/_search?filter_path=aggregations
{
"aggs": {
"price_percentiles": {
"percentiles": {
"field": "AvgTicketPrice",
"percents": [
25,
50,
75,
100
]
}
},
"price_percentiles_rank": {
"percentile_ranks": {
"field": "AvgTicketPrice",
"values": [
600,
1200
]
}
}
}
}
输出结果:
{
"aggregations" : {
"price_percentiles_rank" : {
"values" : {
"600.0" : 45.41644793599837,
"1200.0" : 100.0
}
},
"price_percentiles" : {
"values" : {
"25.0" : 410.01103863927534,
"50.0" : 640.3872852064159,
"75.0" : 842.2604821407433,
"100.0" : 1199.72900390625
}
}
}
}
pecrentiles聚集通过pecrents参数设置组百分比,然后按值由小到大的顺序划分不同区间,每个区间对应一个百分比。percentile_ranks聚集则通过value参数设置组值,然后根据这些值分别计算落在不同值区间的百分比。
以示例返回的结果为例:在pecrentiles返回结果price_percentiles中,"25.0" : 410.01103863927534
代表的含义是25%的机票价格都小于410.01103863927534,其他以此类推。在percentile_ranks返回结果price_percentiles_rank中, "600.0" : 45.41644793599837
代表的含义是600.0以下的机票占总机票价格的百分比为
45.41644793599837%。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。