15、ES实战:桶聚合

本学习笔记基于ElasticSearch 7.10版本,旧版本已经废弃的聚合功能暂时不做笔记,以后有涉及到再做补充。
参考官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.10/search-aggregations-bucket.html

1、Terms

Terms 用于分组聚合,例如,统计各个出版社出版的图书总数量:

GET books/_search
{
   
     
  "aggs": {
   
     
    "bucket_terms": {
   
     
      "terms": {
   
     
        "field": "publish.size",
        "size": 20
      }
    }
  }
}

统计结果如下:
*
注意: terms 分组聚合不能作用于 text 类型,这里我们用的是 keyword 类型的子域 publish.size。

terms 分组聚合的基础上,还可以对每个桶今夕指标聚合,统计不同出版社所出版的图书平均价格:

GET books/_search
{
   
     
  "aggs": {
   
     
    "bucket_terms": {
   
     
      "terms": {
   
     
        "field": "publish.size",
        "size": 20
      },
      "aggs": {
   
     
        "agg_price": {
   
     
          "avg": {
   
     
            "field": "price"
          }
        }
      }
    }
  }
}

*

2、Filter

Filter 是过滤器聚合,可以将符合过滤器中条件的文档分到一个桶中,然后可以求其平均值。例如查询书名中包含 java 的图书的平均价格:

GET books/_search
{
   
     
  "aggs": {
   
     
    "bucket_filter": {
   
     
      "filter": {
   
     
        "term": {
   
     
          "name": "java"
        }
      },
      "aggs": {
   
     
        "avg_price": {
   
     
          "avg": {
   
     
            "field": "price"
          }
        }
      }
    }
  }
}

3、Filters

多过滤器聚合。过滤条件可以有多个。例如查询书名中包含 java 或者 office 的图书的平均价格:

GET books/_search
{
   
     
  "aggs": {
   
     
    "bucket_filters": {
   
     
      "filters": {
   
     
        "filters": [
          {
   
     
            "term": {
   
     
              "name": "java"
            }
          },
          {
   
     
            "term": {
   
     
              "name": "office"
            }
          }
        ]
      },
      "aggs": {
   
     
        "avg_price": {
   
     
          "avg": {
   
     
            "field": "price"
          }
        }
      }
    }
  }
}

4、Range

按照范围聚合,在某一个范围内的文档数统计。例如统计图书价格在 0-50、50-100、100-150、150以上的图书数量:

GET books/_search
{
   
     
  "aggs": {
   
     
    "bucket_range": {
   
     
      "range": {
   
     
        "field": "price",
        "ranges": [
          {
   
     
            "to": 50
          },{
   
     
            "from": 50,
            "to": 100
          },{
   
     
            "from": 100,
            "to": 150
          },{
   
     
            "from": 150
          }
        ]
      }
    }
  }
}

5、Date Range

Range 聚合和 Date Range 聚合都可以可以统计日期,后者的优势在于可以使用日期表达式。

首先造一些测试数据:

PUT blog/_doc/1
{
   
     
  "title":"java",
  "date":"2018-12-30"
}
PUT blog/_doc/2
{
   
     
  "title":"java",
  "date":"2020-12-30"
}
PUT blog/_doc/3
{
   
     
  "title":"java",
  "date":"2022-10-30"
}

统计一年前到一年后的微博数量:

GET blog/_search
{
   
     
  "aggs": {
   
     
    "bucket_date_range": {
   
     
      "date_range": {
   
     
        "field": "date",
        "ranges": [
          {
   
     
            "from": "now-10M/M",
            "to": "now+1y/y"
          }
        ]
      }
    }
  }
}

有关 date range 的日期表达式参数,可以参考官网:ElasticSearch 日期表达式参数

6、Date Histogram

时间直方图聚合。例如统计各个月份的博客数量:

GET blog/_search
{
   
     
  "aggs": {
   
     
    "bucket_date_his": {
   
     
      "date_histogram": {
   
     
        "field": "date",
        "calendar_interval": "month"
      }
    }
  }
}

7、Missing

空值聚合。统计所有没有 price 字段的文档:

GET books/_search
{
   
     
  "aggs": {
   
     
    "bucket_missing": {
   
     
      "missing": {
   
     
        "field": "price"
      }
    }
  }
}

8、Children

可以根据父子文档关系进行分桶。查询子类型为 student 的文档数量:

GET stu_class/_search
{
   
     
  "aggs": {
   
     
    "bucket_children": {
   
     
      "children": {
   
     
        "type": "student"
      }
    }
  }
}

9、Geo Distance

对地理位置数据做统计。例如分别统计 (34.288991865037524,108.9404296875) 坐标方圆 600KM 和 超过 600KM 的城市数量:

GET geo/_search
{
   
     
  "aggs": {
   
     
    "bucket_geo": {
   
     
      "geo_distance": {
   
     
        "field": "location",
        "origin": {
   
     
          "lat": 34.288991865037524,
          "lon": 108.9404296875
        },
        "unit": "km", 
        "ranges": [
          {
   
     
            "to": 600
          },{
   
     
            "from": 600
          }
        ]
      }
    }
  }
}

10、IP Range

IP地址范围聚合。例如查询指定 IP 地址的博客数量:

# 之前的 blog 索引没有设置 ip 字段,删掉重新设置一下
DELETE blog

PUT blog
{
   
     
  "mappings": {
   
     
    "properties": {
   
     
      "ip": {
   
     
        "type": "ip"
      }
    }
  }
}

PUT blog/_doc/1
{
   
     
  "title":"java",
  "date":"2018-12-30",
  "ip":"127.0.0.1"
}
PUT blog/_doc/2
{
   
     
  "title":"java",
  "date":"2020-12-30",
  "ip":"127.0.0.5"
}
PUT blog/_doc/3
{
   
     
  "title":"java",
  "date":"2022-10-30",
  "ip":"127.0.0.10"
}

GET blog/_search
{
   
     
  "aggs": {
   
     
    "bucket_ip_range": {
   
     
      "ip_range": {
   
     
        "field": "ip",
        "ranges": [
          {
   
     
            "from": "127.0.0.5",
            "to": "127.0.0.11"
          }
        ]
      }
    }
  }
}

版权声明:

本文仅记录ElasticSearch学习心得,如有侵权请联系删除。
更多内容请访问原创作者:江南一点雨
*

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: