elasticsearch-聚合(七)

参考:

https://blog.csdn.net/zyc88888/article/details/83016513

聚合几种类型

1.Bucketing桶分聚合:

根据filed或者脚本将相同的数据放到一组

2.Metric:指标聚合:

对文档的指定字段进行计算 max min sum等

3.Pipeline:管道聚合

对其他聚合的结果进行聚合

聚合的语法

 
"aggregations" : {                                //定义聚合对象,也可用 "aggs"
      "<aggregation_name>" : {                    //聚合的名称,用户自定义
          "<aggregation_type>" : {                //聚合类型,比如 "histogram"
              <aggregation_body>                  //每个聚合类型都有其自己的结构定义
          }
          [,"meta" : {  [<meta_data_body>] } ]?
          [,"aggregations" : { [<sub_aggregation>]+ } ]?    //可以定义多个 sub-aggregation
      }
      [,"<aggregation_name_2>" : { ... } ]*       //定义额外的多个平级 aggregation,只有 Bucketing 类型才有意义
}

Metric聚合

group By

"aggs": {
        "depotCode": {
            "terms": {
                "size":600,//默认会聚合10个 这里设置预期最大值
                "field": "depotCode" 
            }
        }
    }

 

avg(avg)

配置参数

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

求平均值

#sql select avg(price1) from product where category=337063315819859968
{
    "size":0,
     "query":{
         "term":{
             "category":"337063315819859968"//查询指定分类产品
         }
     },
    "aggs": {
        "price_avg": {
            "avg": {
                "field": "price1"//计算平均值
            }
        }
    }
}

输出:

{
    "took": 70,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "failed": 0
    },
    "hits": {
        "total": 650241,
        "max_score": 0.0,
        "hits": []
    },
    "aggregations": {
        "price_avg": {
            "value": 48029.56151334659
        }
    }
}
View Code

MAX

配置参数

  • field:用于计算的字段
  • script:由脚本生成用来计算的 value
  • missing:文档缺省字段时的默认值
#select  max(price1) max_price from product where category=337063315819859968
{
"size":0,
 "query":{
         "term":{
             "category":"337063315819859968"//查询指定分类产品
         }
     },
    "aggs": {
        "max_price": {//自定义命名
            "max": {
                "field": "price1" //求最大值的字段
            }
        }
    }
}

Min

配置参数

  • field:用于计算的字段
  • script:由脚本生成用来计算的 value
  • missing:文档缺省字段时的默认值
#select  min(price1) min_price from product where category=337063315819859968
{
"size":0,
 "query":{
         "term":{
             "category":"337063315819859968"//查询指定分类产品
         }
     },
    "aggs": {
        "min_price": {//自定义命名
            "max": {
                "field": "price1" //求最小值的字段
            }
        }
    }
}

Sum


#select  sum(stock) sum_stock from product where category=337063315819859968
{
"size":0,
 "query":{
         "term":{
             "category":"337063315819859968"
         }
     },
    "aggs": {
        "sum_stock": {
            "sum": {
                "field": "stock" 
            }
        }
    }
}

count

#select count(brand) from product
{
"size":0, "aggs" : { "grades_count" : { "value_count" : { "field" : "brand" } } //计算 grade 字段共有多少个值,和 cardinality 聚合不同的 } }

Cardinality(DISTINCT count)

配置参数

  • field:用于计算的字段
  • script:由脚本生成用来计算的 value
  • precision_threshold:
  • missing:文档缺省字段时的默认值
#select count(DISTINCT product_type) from pro_product p where p.product_code in('707440097123094530','ZY599811920987955200') 
{
    "size":0,
     "query":{
         "terms":{
             "productCode":["707440097123094530","ZY599811920987955200"] //in查询
         }
     },
    "aggs": {
        "name_cardinality": {
            "cardinality": {
                "field": "productType" //productType去重统计
            }
        }
    }
}

输出:

{
    "took": 4,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "failed": 0
    },
    "hits": {
        "total": 2,
        "max_score": 0.0,
        "hits": []
    },
    "aggregations": {
        "name_cardinality": {
            "value": 1
        }
    }
}
View Code

stats(多指数统计)

配置参数

  • field:用于计算的字段
  • script:由脚本生成用来计算的 value
  • missing:文档缺省字段时的默认值
#select count(1),max(price1),min(price1),avg(price1),sum(price1) from pro_product p where p.category_id =337063315819859968
{
    "size":0,
     "query":{
         "term":{
             "category":337063315819859968 #查询指定分类
         }
     },
    "aggs": {
        "price1_stats": {
            "stats": {
                "field": "price1"  #统计字段
            }
        }
    }
}

输出结果

{
    "took": 1299,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "failed": 0
    },
    "hits": {
        "total": 650260,
        "max_score": 0.0,
        "hits": []
    },
    "aggregations": {
        "price1_stats": {
            "count": 650260, //总数
            "min": 0.0,//最小值
            "max": 1.894667E7,//最大值
            "avg": 48029.07665856734,//平均值
            "sum": 3.1231387388E10//求和
        }
    }
}
View Code

stats扩展

{
    "size":0,
     "query":{
         "term":{
             "category":337063315819859968
         }
     },
    "aggs": {
        "price1_stats": {
            "extended_stats": {
                "field": "price1" 
            }
        }
    }
}

输出

{
    "took": 1015,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "failed": 0
    },
    "hits": {
        "total": 650260,
        "max_score": 0.0,
        "hits": []
    },
    "aggregations": {
        "price1_stats": {
            "count": 650260,//条数
            "min": 0.0,//最小值
            "max": 1.894667E7,//最大值
            "avg": 48029.07665856734,//平局值
            "sum": 3.1231387388E10,//总和
            "sum_of_squares": 2.4913556601468932E16,//平方和
            "variance": 3.600643112363865E10,//方差
            "std_deviation": 189753.6063521288,标准差
            "std_deviation_bounds": {//平均值/加减两个标准查的值
                "upper": 427536.28936282493,
                "lower": -331478.1360456902
            }
        }
    }
}
View Code

geo_bounds(最小矩形)

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

这个聚合操作计算能够覆盖所有查询结果中geo_point的最小区域,返回的是覆盖所有位置的最小矩形

{
    "size":0,
     "query":{
         "term":{
             "category":337063315819859968 //指定分类产品
         }
     },
    "aggs": {
        "getpoint_geo_bounds": {
            "geo_bounds": {
                "field": "geoPoint" //销售门店经纬度
            }
        }
    }
}

输出

{
    "took": 748,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "failed": 0
    },
    "hits": {
        "total": 650260,
        "max_score": 0.0,
        "hits": []
    },
    "aggregations": {
        "getpoint_geo_bounds": {
            "bounds": {
                "top_left": {#左上角精度维度
                    "lat": 52.945659,
                    "lon": 0.0
                },
                "bottom_right": {#右下角精度维度
                    "lat": 0.0,
                    "lon": 131.162756
                }
            }
        }
    }
}
View Code

Centroid(重心经纬度)

暂时不知道有啥用(重心点经纬度?)

{
    "size":0,
     "query":{
         "term":{
             "category":337063315819859968
         }
     },
    "aggs": {
        "geoPoint_centroid": {
            "geo_centroid": {
                "field": "geoPoint" 
            }
        }
    }
}

geo_distance(指定坐标附近距离聚合)

Percentiles Aggregation

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

{
  "size": 0,
  "aggs": {
    "latency_percentiles": {
      "percentiles": {
        "field": "latency",
        "percents": [ ##统计50% 95% 99的%的百分位
          50,
          95,
          99
        ]
      }
    },
    "latency_avg": {
      "avg": {
        "field": "latency" #请求耗时字段
      }
    }
  }
}

输出

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 12,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "latency_avg": {
      "value": 201.91666666666666
    },
    "latency_percentiles": {
      "values": {
        "50.0": 108.5, #50%的请求访问在 108毫秒
        "95.0": 627.4999999999997, #95%的请求耗时627毫秒
        "99.0": 654#百分之99的请求在654毫秒
      }
    }
  }
}

Script Metric Aggregation

  • 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) }",//#如果type=sale 则计算amout
                "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"#未测试不太理解
            }
        }
    }
}

运行机制:

1. 在每个分组文档遍历(或匹配之前),执行init_script脚本,初始化统计变量。

2. 在遍历每个匹配的分组文档时,执行map_script脚本。

3. 在每个shards(分片)遍历完所有的分组文档时,执行combine_script脚本,得到每个分片的汇总统计结果。

4. 每个shards分片的结果会收集起来汇总到{"params": { "_aggs":[] } },然后执行reduce_script脚本,得到最终的统计结果。

测试环境不支持脚本 未测试

Top hits Aggregation

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

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

先说我们的一个需求 :同一个商品如果是自营 有多少个门店 就在es里面有多少个文档,表示商品id会重复 如果是商家则是一对一关系

需求是 搜索定位最近的商品信息 针对自营门店的则返回一条

以下是es数据结构

 因为测试环境不支持 script 所以以下未做测试 后面再测

{
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "category": 337063315819859968
                }
            }
        }
    },
    "size": 0,
    "aggs": {
        "top-tags": {
            "terms": {
                "_script": "doc['productId']+doc['depotType']", #这里改为script根据 商品id+门店类型进行桶分
                "size": 5
            },
            "aggs": {
                "top_tag_hits": {
                    "top_hits": { 
                        "sort": [{
                            "stock": {   #这里可以改为经纬度排序
                                "order": "desc"
                            }
                        }],
                        "_source": {
                            "include": [
                                "id"  #只取id
                            ]
                        },
                        "size": 1 #取最近一条 每个桶里面的重复数据 支持form 和size 分页
                    }
                }

            }
        }

    }
}

因为es不支持针对聚合结果进行分页,可以只取id然后在内存进行偏移 分页 而且一般前台都是向下滑动分页 商品信息一般不会涉及到深分页

然后根据id 可以走redis 因为我们数据都有全量到redis 从redis获取具体信息 ,或者再查es

Bucket聚合

Histogram Aggregation(multi-bucket)

直方图聚合——基于文档中的某个【数值类型】字段,通过计算来动态的分桶。

公式

rem = value % interval
 
if (rem < 0) {
 
rem += interval
 
}
 
bucket_key = value - rem

配置参数

field:字段,必须为数值类型
interval:分桶间距
min_doc_count:最少文档数桶过滤,只有不少于这么多文档的桶才会返回
extended_bounds:范围扩展
order:对桶排序,如果 histogram 聚合有一个权值聚合类型的"直接"子聚合,那么排序可以使用子聚合中的结果
offset:桶边界位移,默认从0开始
keyed:hash结构返回,默认以数组形式返回每一个桶
missing:配置缺省默认值

{
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "category": 337063315819859968
                }
            }
        }
    },
    "size": 0,
    "aggs": {
        "productId": {
            "histogram": {
                "field": "price1",
                "interval":50,
                "min_doc_count" : 1,
                "extended_bounds" : {
                    "min" : 0,
                    "max" : 500
                },
                "order" : { "_count" : "desc" },
                "keyed":true
            }
        }
    }
}

Data Histogram Aggregation

统计某个时间修改数据

日期直方图聚合——基于日期类型,以【日期间隔】来桶分聚合。

可用的时间间隔类型为:year、quarter、month、week、day、hour、minute、second,其中,除了year、quarter 和 month,其余可用小数形式。

配置参数

  • field:
  • interval:
  • format:定义日期的格式,配置后会返回一个 key_as_string 的字符串类型日期(默认只有key)
  • time_zone:定义时区,用作时间值的调整
  • offset:
  • missing:
{
    "size":0,
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "category": 337063315819859968
                }
            }
        }
    },    
    "aggs" : {
        "articles_over_time" : {
            "date_histogram" : {
                "field" : "lastUpdateTime",
                "interval" : "month",
                "format" : "yyyy-MM-dd",
                "time_zone": "+08:00"
            }
        }
    }
}
原文地址:https://www.cnblogs.com/LQBlog/p/10539245.html