zoukankan      html  css  js  c++  java
  • 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"
                }
            }
        }
    }
  • 相关阅读:
    Java对象的生命周期与作用域的讨论(转)
    [置顶] Oracle学习路线与方法
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
  • 原文地址:https://www.cnblogs.com/LQBlog/p/10539245.html
Copyright © 2011-2022 走看看