首页 > 其他分享 >16.ElasticSearch系列之深入聚合分析

16.ElasticSearch系列之深入聚合分析

时间:2022-10-20 21:24:49浏览次数:72  
标签:聚合 keyword 16 field ElasticSearch aggs terms type size

深入理解聚合分析原理及精确性问题

1. Metric Aggregation

  • 单值分析,只输出一个分析结果

    • min max avg sum
    • cardinality (类似distinct count)
  • 多值分析,输出多个分析结果

    • stats extended stats
    • percentile, percentile rank
    • top hits(排在前面的示例)
# 聚合所有类型type,统计唯一值数量
POST kibana_sample_data_ecommerce/_search
{
  "size": 0, 
  "aggs": {
    "type": {
      "cardinality": {
        "field": "type"
      }
    }
  }
}
# 求价格中位数
GET kibana_sample_data_flights/_search
{
  "size": 0,
  "aggs": {
    "AvgTicketPrice": {
      "percentiles": {
        "field": "AvgTicketPrice",
        "percents": [
          50
        ]
      }
    }
  }
}
# 对嵌套类型detail_info中price聚合
GET poi/_search
{
  "size": 0,
  "aggs": {
    "detail_info": {
      "nested": {
        "path": "detail_info"
      },
      "aggs": {
        "price": {
          "stats": {
            "field": "detail_info.price"
          }
        }
      }
    }
  }
}

2. Bucket Aggregation

  • 按照一定的规则,将文档分配到不同的桶中。ES提供了常见的Bucket Aggregation
    • Terms
    • 数字类型
      • Range / Date Range
      • Histogram / Date Histogram
  • 支持嵌套:也就是在桶中继续分桶

一个较为复杂的聚合示例:获取城市某个时间段的移动平均中位数

def get_city_median(city, start_time, end_time):
    return es.elastic_client.search(body={
            "query": {
                "bool": {
                    "must": [
                        {
                            "term": {
                                "city": city
                            }
                        }
                    ],
                    "filter": [
                        {
                            "range": {
                                "publish_date": {
                                    "gt": start_time,
                                    "lte": end_time
                                }
                            }
                        }
                    ]
                }
            },
            "size": 0,
            "aggs": {
                "group_by_city": {
                    "terms": {
                        "field": "city"
                    },
                    "aggs": {
                        "group_by_date": {
                            "date_histogram": {
                                "field": "publish_date",
                                "calendar_interval": "month",
                                "format": "yyyy-MM"
                            },
                            "aggs": {
                                "avg_price_percentile": {
                                    "percentiles": {
                                        "field": "avg_price",
                                        "percents": [50]
                                    }
                                },
                                 "the_movperc": { // 用到了下面所说的管道概念
                                      "moving_percentiles": {
                                        "buckets_path": "avg_price_percentile",   
                                        "window": 3
                                      }
                                }
                            }
                        }
                    }
                }
            }
        }, index='xxxx')

3. Pipeline Aggregation

  • 管道的概念:支持对聚合结果分析,再次进行聚合分析
  • Pipeline的分析结果会输出在原结果中,根据位置的不同,分为两类
    • Sibling - 结果和现有分析结果同级
      • Max Min Avg Sum Bucket
      • Stats Extended Stats Bucket
      • Percentiles Bucket
    • Parent - 结果内嵌在现有的聚合分析结果之中
      • Derivative(求导)
      • Cumultive Sum(累计求和)
      • Moving Function(滑动窗口)
# 聚合费用最少的飞行目的地
GET kibana_sample_data_flights/_search
{
  "size": 0,
  "aggs": {
    "dest": {
      "terms": {
        "field": "Dest",
        "size": 10
      },
      "aggs": {
        "price": {
          "avg": {
            "field": "AvgTicketPrice"
          }
        }
      }
    },
    "min_dest_price": {
      "min_bucket": {
        "buckets_path": "dest>price"
      }
    }
  }
}

4. 聚合作用范围

#Filter
POST employees/_search
{
  "size": 0,
  "aggs": {
    "older_person": {
      "filter":{ // filter在该聚合中过滤生效
        "range":{
          "age":{
            "from":35
          }
        }
      },
      "aggs":{
         "jobs":{
           "terms": {
        "field":"job.keyword"
      }
      }
    }},
    "all_jobs": {
      "terms": {
        "field":"job.keyword"
        
      }
    }
  }
}
POST employees/_search
{
  "aggs": {
    "jobs": {
      "terms": {
        "field": "job.keyword"
      }
    }
  },
  "post_filter": { // 筛选聚合后符合条件的结果
    "match": {
      "job.keyword": "Dev Manager"
    }
  }
}
#global
POST employees/_search
{
  "size": 0,
  "query": {
    "range": {
      "age": {
        "gte": 40
      }
    }
  },
  "aggs": {
    "jobs": {
      "terms": {
        "field":"job.keyword"
        
      }
    },
    "all":{
      "global":{}, // 忽略全局范围过滤,筛选所有年龄段
      "aggs":{
        "salary_avg":{
          "avg":{
            "field":"salary"
          }
        }
      }
    }
  }
}

5. 聚合分析的原理及精确性问题

分布式系统的近似统计算法

http://shenjianblog.oss-cn-shanghai.aliyuncs.com/pic/20220906/680ffd414e1141b6968e85e38a2b7cf2-ES4.png

GET kibana_sample_data_flights/_search
{
  "size": 0,
  "aggs": {
    "dest": {
      "terms": {
        "field": "Dest",
        "size": 10
      }
    }
  }
}
// 返回结果
"aggregations" : {
    "dest" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 8898
    }
}

在Terms Aggregation的返回中有两个特殊的数值

  • doc_count_error_upper_bound: 被遗漏的term分桶包含的文档,有可能的最大值
  • sum_other_doc_count:ES除了返回结果bucket的terms外,该参数返回其他terms的文档总数(总数-返回的文档总数)

其中,当doc_count_error_upper_bound大于0的时候,可能结果不准

  • 不准原因为,数据分散在多个分片上,Coordinating Node无法获取数据全貌
  • 解决方案1:当数据量不大时,设置Primary Shard为1,实现准确性
  • 解决方案2:在分布式数据上,设置shard_size参数,提高精确度
    • 原理:每个从Shard上额外多获取数据,提升准确性
    • 调整shard_size大小,降低doc_count_error_upper_bound来提升准确度
      • 增加整体计算量,提高了准确度,但会降低相应时间
    • shard_size默认大小=size*1.5+10
DELETE my_flights
PUT my_flights
{
  "settings": {
    "number_of_shards": 20
  },
  "mappings" : {
      "properties" : {
        "AvgTicketPrice" : {
          "type" : "float"
        },
        "Cancelled" : {
          "type" : "boolean"
        },
        "Carrier" : {
          "type" : "keyword"
        },
        "Dest" : {
          "type" : "keyword"
        },
        "DestAirportID" : {
          "type" : "keyword"
        },
        "DestCityName" : {
          "type" : "keyword"
        },
        "DestCountry" : {
          "type" : "keyword"
        },
        "DestLocation" : {
          "type" : "geo_point"
        },
        "DestRegion" : {
          "type" : "keyword"
        },
        "DestWeather" : {
          "type" : "keyword"
        },
        "DistanceKilometers" : {
          "type" : "float"
        },
        "DistanceMiles" : {
          "type" : "float"
        },
        "FlightDelay" : {
          "type" : "boolean"
        },
        "FlightDelayMin" : {
          "type" : "integer"
        },
        "FlightDelayType" : {
          "type" : "keyword"
        },
        "FlightNum" : {
          "type" : "keyword"
        },
        "FlightTimeHour" : {
          "type" : "keyword"
        },
        "FlightTimeMin" : {
          "type" : "float"
        },
        "Origin" : {
          "type" : "keyword"
        },
        "OriginAirportID" : {
          "type" : "keyword"
        },
        "OriginCityName" : {
          "type" : "keyword"
        },
        "OriginCountry" : {
          "type" : "keyword"
        },
        "OriginLocation" : {
          "type" : "geo_point"
        },
        "OriginRegion" : {
          "type" : "keyword"
        },
        "OriginWeather" : {
          "type" : "keyword"
        },
        "dayOfWeek" : {
          "type" : "integer"
        },
        "timestamp" : {
          "type" : "date"
        }
      }
    }
}

POST _reindex
{
  "source": {
    "index": "kibana_sample_data_flights"
  },
  "dest": {
    "index": "my_flights"
  }
}

GET my_flights/_search
{
  "size": 0,
  "aggs": {
    "weather": {
      "terms": {
        "field":"OriginWeather",
        "size":1,
        "shard_size":10 // 当设置为5时,可以看到返回的doc_count_error_upper_boundda大于0,10则为0
      }
    }
  }
}

欢迎关注公众号算法小生沈健的技术博客

标签:聚合,keyword,16,field,ElasticSearch,aggs,terms,type,size
From: https://www.cnblogs.com/shenjian-online/p/16811341.html

相关文章

  • 11.ElasticSearch系列之搜索相关性算分机制
    1.相关性和相关性算分1.1相关性搜索的相关性算分,描述了一个文档和查询语句匹配的程度。ES会对每个匹配查询条件的结果进行算分_score打分的本质是排序,需要把最符合用......
  • CF1163F Indecisive Taxi Fee
    题意给定一张无向图,每次询问为更改一条边的边权后,从\(1\)到\(n\)的最短路。Solution首先考虑有哪些情况。如果原图中\(1\ton\)的最短路为路径\(P\),其上第\(i\)......
  • Hyperf使用ElasticSearch记录
    Hyperf安装Elasticsearch协程客户端hyperf/elasticsearch主要为elasticsearch-php进行了客户端对象创建的工厂类封装,elasticsearch-php默认使用GuzzleRing客户......
  • Elasticsearch 字段折叠的使用
    在Elasticsearch5.x有一个字段折叠(FieldCollapsing,#22337)的功能非常有意思,在这里分享一下, 字段折叠是一个很有历史的需求了,可以看这个issue,编号#256,最初是2010年7月......
  • CF1601C Optimal Insertion 解题报告
    确实是一道好题模拟赛打挂了题意给定两个序列\(a,b\),长度分别为\(n,m(1\leqn,m\leq10^6)\))。接下来将\(b\)中的所有元素以任意方式插入序列\(a\)中任意位置,请......
  • AcCoders 10477:【省选基础数据结构 树链剖分】【GDOI2016】疯狂动物城 题解
    算法:树链剖分,可持久化线段树。题目大意给定\(n\)个结点的一棵树,\(m\)次操作,操作有三种:将\(x\)至\(y\)最短路径上的所有点的权值加上\(delta\)。对于\(x\)至......
  • U161009 [雅礼集训 2017 Day1] 市场
    题目链接U161009[雅礼集训2017Day1]市场题目背景从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落......
  • 【luogu CF1163F】Indecisive Taxi Fee(图论)(分类讨论)
    IndecisiveTaxiFee题目链接:luoguCF1163F题目大意给你一个无向图,每次改一条边的权值(每次都会变回来),问你1~n的最短路长度。思路考虑分类讨论,先找到最短路的路径,然......
  • 关于报出这样的错误:org.apache.catalina.core.StandardWrapperValve.invoke 在路径为/
    从23:30开始报错检查,现在才弄好,发出来分享一下错误界面:首先,我们需要检查一下我们利用DBUtil.java文件中引用的db文件名称是否正确,(我就是因为没有注意到文件名称是否正确......
  • DFS练习: POJ1010 POJ1011 POJ1020 POJ1321 POJ1416 POJ1724
    POJ1010packagepoj1010;importjava.util.Arrays;importjava.util.Scanner;/***@Authorjinjun99*@DateCreatedin2022/10/418:11*@Description*@S......