ElasticSearch学习笔记(八) 聚合之Bucket详解

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch 聚合(Aggregation)是 Elasticsearch 中用于处理搜索结果的重要工具之一。它可以帮助我们对搜索结果进行各种数据统计和分析,以便更好地理解搜索结果数据的特征和趋势。

Elasticsearch 聚合(Aggregation)是 Elasticsearch 中用于处理搜索结果的重要工具之一。它可以帮助我们对搜索结果进行各种数据统计和分析,以便更好地理解搜索结果数据的特征和趋势。

当我们需要对 Elasticsearch 中的文档集合进行分组计算时,就需要使用到 Bucket(桶)聚合。Bucket 聚合是 Elasticsearch 中一种基于文档集合进行切分的聚合方式,它将文档集合分成多个 bucket,并对每个 bucket 进行计算和分析。

Bucket 聚合可以按照文档的字段值、时间范围、地理位置等多种方式来进行切分,并提供丰富的聚合操作来计算每个 bucket 的指标。

下面我们使用一个商品索引的数据来演示几种常用的Bucket聚合用法

#准备索引及数据
PUT /product-test
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "brand":{
        "type": "keyword"
      },
      "image": {
        "type": "keyword"
      },
      "price": {
        "type": "float"
      },
      "quantity": {
        "type": "integer"
      }
    }
  }
}

POST /product-test/_bulk
{ "index": { "_id": 1 }}
{ "name": "苹果12 Pro Max","brand":"apple", "image": "https://images.com/iphone12promax.jpg", "price": 4000, "quantity": 50 }
{ "index": { "_id": 2 }}
{ "name": "Samsung Galaxy S21 Ultra","brand":"三星", "image": "https://images.com/SamsungS21.jpg", "price": 6200, "quantity": 100 }
{ "index": { "_id": 3 }}
{ "name": "苹果14 Mini", "brand":"apple","image": "https://images.com/iphone14mini.jpg", "price": 6999, "quantity": 200 }
{ "index": { "_id": 4 }}
{ "name": "苹果14 Pro Max", "brand":"apple","image": "https://images.com/iphone12promax.jpg", "price": 8999, "quantity": 250 }
{ "index": { "_id": 5 }}
{ "name": "华为Mate 40 Pro", "brand":"华为","image": "https://images.com/HuaweiMate40.jpg", "price": 5999, "quantity": 50 }
{ "index": { "_id": 6 }}
{ "name": "小米14", "brand":"小米","image": "https://images.com/xiaomi14.jpg", "price": 5999, "quantity": 50 }

terms 聚合

terms 聚合将文档集合按照指定字段的值进行分组。

例如,我们对商品索引中的品牌字段进行 Terms 聚合,得到每个分类下的商品库存总量。

POST /product-test/_search
{
   
  "size":0,
  "aggs": {
   
    "brand_bucket":{
   
       "terms": {
            
       "field": "brand"    
     },
     "aggs":{
   
       "total_quantity": {
   
          "sum": {
   
            "field": "quantity"
          }
        }
     }
    }
  }
}

返回结果

{
   
  "took" : 59,
  "timed_out" : false,
  "_shards" : {
   
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
   
    "total" : {
   
      "value" : 6,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
   
    "brand_bucket" : {
   
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
   
          "key" : "apple",
          "doc_count" : 3,
          "total_quantity" : {
   
            "value" : 500.0
          }
        },
        {
   
          "key" : "三星",
          "doc_count" : 1,
          "total_quantity" : {
   
            "value" : 100.0
          }
        },
        {
   
          "key" : "华为",
          "doc_count" : 1,
          "total_quantity" : {
   
            "value" : 50.0
          }
        },
        {
   
          "key" : "小米",
          "doc_count" : 1,
          "total_quantity" : {
   
            "value" : 50.0
          }
        }
      ]
    }
  }
}

在结果中,我们可以看到按照品牌字段进行划分,得到了4个品牌的聚合结果,同时将每个品牌的库存总量一起返回了出来。

range 聚合

range 聚合将文档集合按照指定范围进行分组。

例如,我们可以使用下面的查询语句将商品索引中所有文档按照指定价格分为三个区间,并返回每个区间中文档的库存数量的和:

POST /product-test/_search
{
   
  "size":0,
  "aggs": {
   
    "price_range":{
   
       "range": {
            
       "field": "price"  ,
       "ranges": [
          {
   
            "from":0,
            "to": 5000
          },
          {
   
            "from": 5001,
            "to": 8000
          },
          {
   
            "from": 8001
          }
        ]
     },
     "aggs":{
   
       "total_quantity": {
   
          "sum": {
   
            "field": "quantity"
          }
        }
     }
    }
  }
}

返回结果

{
   
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
   
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
   
    "total" : {
   
      "value" : 6,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
   
    "price_range" : {
   
      "buckets" : [
        {
   
          "key" : "0.0-5000.0",
          "from" : 0.0,
          "to" : 5000.0,
          "doc_count" : 1,
          "total_quantity" : {
   
            "value" : 50.0
          }
        },
        {
   
          "key" : "5001.0-8000.0",
          "from" : 5001.0,
          "to" : 8000.0,
          "doc_count" : 4,
          "total_quantity" : {
   
            "value" : 400.0
          }
        },
        {
   
          "key" : "8001.0-*",
          "from" : 8001.0,
          "doc_count" : 1,
          "total_quantity" : {
   
            "value" : 250.0
          }
        }
      ]
    }
  }
}

可以看到,按照商品价格指定范围进行划分,得到了三个聚合结果,每个聚合结果表示一个价格区间内的商品数量和库存总和。

histogram 聚合

histogram 聚合操作会根据指定的某个字段的数值范围对文档集合进行分组。

例如,我们可以使用下面的查询语句将商品索引中所有文档按照价格分组,每个分组的范围为2000:

POST /product-test/_search
{
   
  "size":0,
  "aggs": {
   
    "price_histogram":{
   
       "histogram": {
            
       "field": "price",     
       "interval": 2000     
     }
    }
  }
}

返回结果

{
   
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
   
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
   
    "total" : {
   
      "value" : 6,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
   
    "price_histogram" : {
   
      "buckets" : [
        {
   
          "key" : 4000.0,
          "doc_count" : 3
        },
        {
   
          "key" : 6000.0,
          "doc_count" : 2
        },
        {
   
          "key" : 8000.0,
          "doc_count" : 1
        }
      ]
    }
  }
}

可以看到,按照商品价格区间进行划分,得到了三个聚合结果,每个聚合结果表示一个价格区间内的商品数量。

ip_range 聚合

ip_range 聚合将文档集合按照 IP 地址范围进行分组。

例如,我们可以使用下面的查询语句将 ip_address 索引中所有文档按照 IP 地址的范围分为两个区间,并返回每个区间中文档的数量:

GET /ip_address/_search
{
   
  "size": 0,
  "aggs": {
   
    "ip_ranges": {
   
      "ip_range": {
   
        "field": "ip_address",
        "ranges": [
          {
   
            "from": "10.0.0.0",
            "to": "10.255.255.255"
          },
          {
   
            "from": "192.168.0.0",
            "to": "192.168.255.255"
          }
        ]
      }
    }
  }
}

geohash_grid 聚合

geohash_grid 聚合将地理坐标转换为 geohash,并按照 geohash 前缀进行分组。

例如,我们可以使用下面的查询语句将 location 索引中所有文档按照经纬度进行划分,返回每个 geohash 前缀中文档的数量:

GET /location/_search
{
   
  "size": 0,
  "aggs": {
   
    "locations": {
   
      "geohash_grid": {
   
        "field": "coordinates",
        "precision": 5
      }
    }
  }
}

filters 聚合

filters 聚合根据指定条件对文档集合进行分组。

例如,我们可以使用下面的查询语句将商品索引中品牌为'apple' 的数据统计出来并计算库存总和:

POST /product-test/_search
{
   
  "size":0,
  "aggs": {
   
    "brand_filter":{
   
       "filters": {
            
        "filters": {
   
          "apple":{
   
            "term": {
   
              "brand": "apple"
            }
          }
        }    
     },
     "aggs": {
   
       "total_quantity": {
   
         "sum": {
   
           "field": "quantity"
         }
       }
     }
    }
  }
}

返回结果

{
   
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
   
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
   
    "total" : {
   
      "value" : 6,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
   
    "brand_filter" : {
   
      "buckets" : {
   
        "apple" : {
   
          "doc_count" : 3,
          "total_quantity" : {
   
            "value" : 500.0
          }
        }
      }
    }
  }
}

significant_terms 聚合

significant_terms 聚合用于找出一个文档集合中比其他文档集合更加显著的词语或短语。

例如,我们可以使用下面的查询语句在 news 索引中所有文档的 content 字段中找出最具有显著性的词语或短语:

GET /news/_search
{
   
  "size": 0,
  "aggs": {
   
    "significant_terms": {
   
      "significant_terms": {
   
        "field": "content"
      }
    }
  }
}

Bucket 聚合操作还可以通过嵌套方式进行组合使用,以实现更复杂的数据分析和计算。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
1月前
|
存储 SQL 监控
|
3月前
|
存储 自然语言处理 关系型数据库
ElasticSearch基础3——聚合、补全、集群。黑马旅游检索高亮+自定义分词器+自动补全+前后端消息同步
聚合、补全、RabbitMQ消息同步、集群、脑裂问题、集群分布式存储、黑马旅游实现过滤和搜索补全功能
|
4月前
|
自然语言处理 Java 关系型数据库
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
162 1
|
6月前
|
SQL 安全 数据挖掘
Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的?
Elasticsearch聚合查询用于复杂数据分析,包括统计空值率。示例展示了如何计算字段`my_field`非空非零文档的百分比。查询分为三步:总文档数计数、符合条件文档数计数及计算百分比。聚合概念涵盖度量、桶和管道聚合。脚本在聚合中用于动态计算。常见聚合类型如`sum`、`avg`、`date_histogram`等。组合使用可实现多值统计、嵌套聚合和空值率计算。[阅读更多](https://zhangfeidezhu.com/?p=515)
320 0
Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的?
|
6月前
|
存储 缓存 自然语言处理
elasticsearch 聚合 : 指标聚合、桶聚合、管道聚合解析使用总结
elasticsearch 聚合 : 指标聚合、桶聚合、管道聚合解析使用总结
|
6月前
|
缓存 Java API
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——聚合与搜索(三)
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——聚合与搜索(三)
|
7月前
|
存储 缓存 Java
Elasticsearch 8.X 聚合查询下的精度问题及其解决方案
Elasticsearch 8.X 聚合查询下的精度问题及其解决方案
202 0
|
1月前
|
存储 安全 数据管理
如何在 Rocky Linux 8 上安装和配置 Elasticsearch
本文详细介绍了在 Rocky Linux 8 上安装和配置 Elasticsearch 的步骤,包括添加仓库、安装 Elasticsearch、配置文件修改、设置内存和文件描述符、启动和验证 Elasticsearch,以及常见问题的解决方法。通过这些步骤,你可以快速搭建起这个强大的分布式搜索和分析引擎。
54 5
|
2月前
|
存储 JSON Java
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
这篇文章是关于Elasticsearch的学习指南,包括了解Elasticsearch、版本对应、安装运行Elasticsearch和Kibana、安装head插件和elasticsearch-ik分词器的步骤。
244 0
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
|
3月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo