• ES聚合查询详解(二):桶聚合


    原文:

    https://laowan.blog.csdn.net/article/details/120847437

    前言
    前面介绍了ES的简单使用,并说明了ES聚合查询主要分为3类:指标聚合、桶聚合和管道聚合。
    本文主要是介绍其中桶聚合的相关使用。

    一、桶聚合
    Bucket 聚合不像Metric聚合那样计算字段上的指标,而是创建多个“存放“文档的桶。每个桶都与一个标准相关联(取决于聚合类型) ,该标准确定当前上下文中的文档是否“落入”它。换句话说,bucket 有效地定义了文档集。除了 bucket 本身之外,bucket 聚合还计算并返回“落入”每个 bucket 中的文档数量。

    与Metric聚合不同的是,Bucket 聚合可以包含子聚合。这些子聚合将聚合它们的“父”bucket 聚合创建的 bucket。

    不同的桶式聚合器有不同的“分桶”策略。有些定义单个桶,有些定义固定数量的多个桶,还有一些在聚合过程中动态创建桶。

    二、使用场景
    桶聚合查询主要用来做分组统计。
    其中每个桶代表一个分组。

    三、桶聚合的分类
    官方文档:桶聚合

    四、典型使用
    1、单值聚合统计 terms
    一个基于多桶值源的聚合,其中桶是动态构建的——每个唯一值一个桶。主要使用做分组个数统计,
    类似mysql中的 select type , count(type) from table group by type;

    示例:统计每个类型的记录数,基于genre的唯一值个数创建多个桶,并统计每个桶的记录数。

    GET /_search
    {
    "aggs": {
    "genres": {
    "terms": { "field": "genre" }
    }
    }
    }
    

    执行结果:

    {
    
    "aggregations": {
    "genres": {
    "doc_count_error_upper_bound": 0,
    "sum_other_doc_count": 0,
    "buckets": [
    {
    "key": "electronic",
    "doc_count": 6
    },
    {
    "key": "rock",
    "doc_count": 3
    },
    {
    "key": "jazz",
    "doc_count": 2
    }
    ]
    }
    }
    }
    

    如果想基于分组的个数排序,可以使用如下语句:

    GET /_search
    {
    "aggs": {
    "genres": {
    "terms": {
    "field": "genre",
    "order": { "_count": "asc" }
    }
    }
    }
    }
    

    如果希望基于分组的key值排序,可以使用如下语句:

    GET /_search
    {
    "aggs": {
    "genres": {
    "terms": {
    "field": "genre",
    "order": { "_key": "asc" }
    }
    }
    }
    }
    

    使用 min_doc_count 选项可以只返回匹配超过配置的命中数的结果:

    GET /_search
    {
    "aggs": {
    "tags": {
    "terms": {
    "field": "tags",
    "min_doc_count": 10
    }
    }
    }
    }
    

    2、时间范围分组date_range
    统计10个月前和近10个月的记录数。

    POST /sales/_search?size=0
    {
    "aggs": {
    "range": {
    "date_range": {
    "field": "date",
    "format": "MM-yyyy",
    "ranges": [
    { "to": "now-10M/M" },
    { "from": "now-10M/M" }
    ]
    }
    }
    }
    }
    

    3、多值分组Multi Terms
    根据多个字段进行分组统计,类比sql:select genre ,product, count(*) from products group by genre,product;

    GET /products/_search
    {
    "aggs": {
    "genres_and_products": {
    "multi_terms": {
    "terms": [{
    "field": "genre"
    }, {
    "field": "product"
    }]
    }
    }
    }
    }
    

    4、自定义分组查询 Range Aggregation
    Range Aggregation基于多桶值源的聚合,使用户能够定义一组范围——每个范围代表一个桶。在聚合过程中,将根据每个 bucket 范围检查从每个文档中提取的值,并对相关/匹配文档进行“ bucket”检查。
    请注意,这个聚合包括 from 值,并为每个范围排除 to 值。

    示例:根据自定义的价格范围统计买卖订单数。

    GET sales/_search
    {
    "aggs": {
    "price_ranges": {
    "range": {
    "field": "price",
    "ranges": [
    { "to": 100.0 },
    { "from": 100.0, "to": 200.0 },
    { "from": 200.0 }
    ]
    }
    }
    }
    }
    

    5、日期分组聚合 Date Histogram
    按月分组聚合:

    POST /sales/_search?size=0
    {
    "aggs": {
    "sales_over_time": {
    "date_histogram": {
    "field": "date",
    "calendar_interval": "month"
    }
    }
    }
    }
    

    按2天的日历单元聚合:

    POST /sales/_search?size=0
    {
    "aggs": {
    "sales_over_time": {
    "date_histogram": {
    "field": "date",
    "calendar_interval": "2d"
    }
    }
    }
    }
    

    6、自动日期分组聚合 Auto Date Histogram
    自动根据日期分组聚合,还提供了一个目标桶数,表示所需桶数,并自动选择桶的间隔,以最好地实现该目标。返回的桶数总是小于或等于这个目标数。Bucket 字段是可选的,如果没有指定,则默认为10个 bucket。
    示例:要求10桶的目标。

    POST /sales/_search?size=0
    {
    "aggs": {
    "sales_over_time": {
    "auto_date_histogram": {
    "field": "date",
    "buckets": 10
    }
    }
    }
    }
    

    7、聚合中使用过滤器filter

    POST /sales/_search?size=0&filter_path=aggregations
    {
    "aggs": {
    "avg_price": { "avg": { "field": "price" } },
    "t_shirts": {
    "filter": { "term": { "type": "t-shirt" } },
    "aggs": {
    "avg_price": { "avg": { "field": "price" } }
    }
    }
    }
    }
    

    8、稀有值查询 Rare terms
    示例:查询桶中最多包含2条记录的类型genre。

    GET /_search
    {
    "aggs": {
    "genres": {
    "rare_terms": {
    "field": "genre",
    "max_doc_count": 2
    }
    }
    }
    }
    

    9、嵌套聚合 Nested Aggregation
    创建嵌套索引

    PUT /products
    {
    "mappings": {
    "properties": {
    "resellers": {
    "type": "nested",
    "properties": {
    "reseller": {
    "type": "keyword"
    },
    "price": {
    "type": "double"
    }
    }
    }
    }
    }
    }
    

    添加数据:

    PUT /products/_doc/0?refresh
    {
    "name": "LED TV",
    "resellers": [
    {
    "reseller": "companyA",
    "price": 350
    },
    {
    "reseller": "companyB",
    "price": 500
    }
    ]
    }
    

    根据嵌套聚合查询:

    GET /products/_search?size=0
    {
    "query": {
    "match": {
    "name": "led tv"
    }
    },
    "aggs": {
    "resellers": {
    "nested": {
    "path": "resellers"
    },
    "aggs": {
    "min_price": {
    "min": {
    "field": "resellers.price"
    }
    }
    }
    }
    }
    }
    

    执行结果:

    {
    
    "aggregations": {
    "resellers": {
    "doc_count": 2,
    "min_price": {
    "value": 350.0
    }
    }
    }
    }
    

    10、缺少聚合 Missing aggregation
    Missing聚合属于单桶聚合,对空值数据统计。

    示例:统计没有价格的产品总数。

    POST /sales/_search?size=0
    {
    "aggs": {
    "products_without_a_price": {
    "missing": { "field": "price" }
    }
    }
    }
    

    11、全局聚合 Global aggregators
    定义搜索执行上下文中所有文档的单个存储桶。此上下文由您正在搜索的索引和文档类型定义,但不受搜索查询本身的影响。

    示例:
    聚合查询all_products中的平均价格统计不受外层query中的查询添加的影响。

    POST /sales/_search?size=0
    {
    "query": {
    "match": { "type": "t-shirt" }
    },
    "aggs": {
    "all_products": {
    "global": {},
    "aggs": {
    "avg_price": { "avg": { "field": "price" } }
    }
    },
    "t_shirts": { "avg": { "field": "price" } }
    }
    }
    

    总结
    本文主要是对ES中典型的桶聚合查询进行了介绍,特别要注意以下几个分组统计。
    1、单值分组统计 Terms aggregation
    2、多值分组统计 Multi Terms
    3、自定义分组统计 Range Aggregation
    4、时间范围分组 date_range

  • 相关阅读:
    Cglib的动态代理
    idea中隐藏.idea文件夹和.iml文件
    JDBC工具类创建及使用
    JDBC的配置及使用入门
    mybatis的入门
    动态代理的具体实现
    【Flask】WTForms基本使用
    【Flask】Flask-Migrate基本使用
    【Flask】Flask-Sqlalchemy使用笔记
    【Flask】Sqlalchemy 子查询
  • 原文地址:https://www.cnblogs.com/cfas/p/16535341.html
Copyright © 2020-2023  润新知