Elasticsearch学习系列四(聚合搜索)
聚合分析
聚合分析是数据库中重要的功能特性,完成对一个查询的集中数据的聚合计算。如:最大值、最小值、求和、平均值等等。对一个数据集求和,算最大最小值等等,在ES中称为指标聚合,而对数据做类似关系型数据库那样的分组(group by),在ES中称为分桶。
语法:
aggregations" : {
"<aggregation_name>" : { <!--聚合的名字 -->
"<aggregation_type>" : { <!--聚合的类型 -->
<aggregation_body> <!--聚合体:对哪些字段进行聚合 -->
}
[,"meta" : { [<meta_data_body>] } ]? <!--元 -->
[,"aggregations" : { [<sub_aggregation>]+ } ]? <!--在聚合里面在定义子聚合 -->
}
[,"<aggregation_name_2>" : { ... } ]*<!--聚合的名字 -->
}
aggregations可以简写为aggs。
指标聚合
示例1:查询所有商品里最贵的价格
size就填0就行。
POST /item/_search
{
"size":0,
"aggs": {
"max_price": {
"max": {
"field": "price"
}
}
}
}
示例2:文档计数
POST /item/_count
{
"query": {
"range": {
"price": {
"gte": 10,
"lte": 5000
}
}
}
}
示例3:统计某字段有值的文档数
POST /item/_search?size=0
{
"aggs": {
"price_count": {
"value_count": {
"field": "price"
}
}
}
}
示例4:用cardinality值去重计数
如果有price重复的,就只会统计去重后的数量
POST /item/_search?size=0
{
"aggs":{
"price_count":{
"cardinality": {
"field": "price"
}
}
}
}
示例5:stats统计count、max、min、avg、sum5个值
POST /item/_search?size=0
{
"aggs":{
"price_stats":{
"stats": {
"field": "price"
}
}
}
}
结果如下:
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 5,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"price_stats" : {
"count" : 5,
"min" : 2333.0,
"max" : 6888.0,
"avg" : 4059.2,
"sum" : 20296.0
}
}
}
示例6:extended stats,stats的增强版,增加了平方和、方差、标准差、平均值加/减两个标准差的区间。
POST /item/_search?size=0
{
"aggs":{
"price_stats":{
"extended_stats": {
"field": "price"
}
}
}
}
查询结果:
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 5,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"price_stats" : {
"count" : 5,
"min" : 2333.0,
"max" : 6888.0,
"avg" : 4059.2,
"sum" : 20296.0,
"sum_of_squares" : 9.9816722E7,
"variance" : 3486239.7599999993,
"std_deviation" : 1867.1474928349928,
"std_deviation_bounds" : {
"upper" : 7793.494985669986,
"lower" : 324.9050143300142
}
}
}
}
示例7:Percentiles 占比百分位对应的值统计
POST /item/_search?size=0
{
"aggs":{
"price_percents":{
"percentiles": {
"field": "price"
}
}
}
}
#指定分位值
POST /item/_search?size=0
{
"aggs":{
"price_percents":{
"percentiles": {
"field": "price",
"percents": [
1,
5,
25,
50,
75,
95,
99
]
}
}
}
}
查询结果:
......
"aggregations" : {
"price_percents" : {
"values" : {
"1.0" : 2333.0000000000005,
"5.0" : 2333.0,
"25.0" : 2599.25,
"50.0" : 2688.0,
"75.0" : 5996.25,
"95.0" : 6888.0,
"99.0" : 6888.0
}
}
}
}
Percentiles rank 统计值小于等于指定值的文档占比
price小于3000和5000的占比
POST /item/_search?size=0
{
"aggs":{
"price_percents":{
"percentile_ranks": {
"field": "price"
, "values": [3000,5000]
}
}
}
}
桶聚合
他执行的是对文档分组的操作,把满足相关特性的文档分到一个桶里,即桶分。输出结果往往是一个个包含多个文档的桶。
示例1:分组求平均值
POST /item/_search
{
"size": 0,
"aggs": {
"group_by_price": {
"range": {
"field": "price",
"ranges": [
{
"from": 50,
"to": 100
},
{
"from": 2000,
"to": 3000
},
{
"from": 3000,
"to": 5000
}
]
},
"aggs": {
"average_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
查询结果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 5,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"group_by_price" : {
"buckets" : [
{
"key" : "50.0-100.0",
"from" : 50.0,
"to" : 100.0,
"doc_count" : 0,
"average_price" : {
"value" : null
}
},
{
"key" : "2000.0-3000.0",
"from" : 2000.0,
"to" : 3000.0,
"doc_count" : 3,
"average_price" : {
"value" : 2569.6666666666665
}
},
{
"key" : "3000.0-7000.0",
"from" : 3000.0,
"to" : 7000.0,
"doc_count" : 2,
"average_price" : {
"value" : 6293.5
}
}
]
}
}
}
示例2:分组的文档个数统计
POST /item/_search
{
"size": 0,
"aggs": {
"group_by_price": {
"range": {
"field": "price",
"ranges": [
{
"from": 50,
"to": 100
},
{
"from": 2000,
"to": 3000
},
{
"from": 3000,
"to": 7000
}
]
},
"aggs": {
"average_price": {
"value_count": {
"field": "price"
}
}
}
}
}
}
示例3:使用having语法
POST /item/_search
{
"size": 0,
"aggs": {
"group_by_price": {
"range": {
"field": "price",
"ranges": [
{
"from": 50,
"to": 100
},
{
"from": 2000,
"to": 3000
},
{
"from": 3000,
"to": 7000
}
]
},
"aggs": {
"average_price": {
"avg": {
"field": "price"
}
},
"having":{
"bucket_selector": {
"buckets_path": {
"avg_price":"average_price"
},
"script": {
"source": "params.avg_price >=2600"
}
}
}
}
}
}
}