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

简介: 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 聚合操作还可以通过嵌套方式进行组合使用,以实现更复杂的数据分析和计算。

相关实践学习
以电商场景为例搭建AI语义搜索应用
本实验旨在通过阿里云Elasticsearch结合阿里云搜索开发工作台AI模型服务,构建一个高效、精准的语义搜索系统,模拟电商场景,深入理解AI搜索技术原理并掌握其实现过程。
ElasticSearch 最新快速入门教程
本课程由千锋教育提供。全文搜索的需求非常大。而开源的解决办法Elasricsearch(Elastic)就是一个非常好的工具。目前是全文搜索引擎的首选。本系列教程由浅入深讲解了在CentOS7系统下如何搭建ElasticSearch,如何使用Kibana实现各种方式的搜索并详细分析了搜索的原理,最后讲解了在Java应用中如何集成ElasticSearch并实现搜索。  
相关文章
|
9月前
|
数据采集 JSON 数据挖掘
Elasticsearch 的DSL查询,聚合查询与多维度数据统计
Elasticsearch的DSL查询与聚合查询提供了强大的数据检索和统计分析能力。通过合理构建DSL查询,用户可以高效地搜索数据,并使用聚合查询对数据进行多维度统计分析。在实际应用中,灵活运用这些工具不仅能提高查询效率,还能为数据分析提供深入洞察。理解并掌握这些技术,将显著提升在大数据场景中的分析和处理能力。
489 20
|
存储 SQL 监控
|
存储 自然语言处理 关系型数据库
ElasticSearch基础3——聚合、补全、集群。黑马旅游检索高亮+自定义分词器+自动补全+前后端消息同步
聚合、补全、RabbitMQ消息同步、集群、脑裂问题、集群分布式存储、黑马旅游实现过滤和搜索补全功能
ElasticSearch基础3——聚合、补全、集群。黑马旅游检索高亮+自定义分词器+自动补全+前后端消息同步
|
自然语言处理 Java 关系型数据库
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
431 1
|
SQL 安全 数据挖掘
Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的?
Elasticsearch聚合查询用于复杂数据分析,包括统计空值率。示例展示了如何计算字段`my_field`非空非零文档的百分比。查询分为三步:总文档数计数、符合条件文档数计数及计算百分比。聚合概念涵盖度量、桶和管道聚合。脚本在聚合中用于动态计算。常见聚合类型如`sum`、`avg`、`date_histogram`等。组合使用可实现多值统计、嵌套聚合和空值率计算。[阅读更多](https://zhangfeidezhu.com/?p=515)
548 0
Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的?
|
存储 缓存 自然语言处理
elasticsearch 聚合 : 指标聚合、桶聚合、管道聚合解析使用总结
elasticsearch 聚合 : 指标聚合、桶聚合、管道聚合解析使用总结
|
缓存 Java API
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——聚合与搜索(三)
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——聚合与搜索(三)
|
8月前
|
安全 Java Linux
Linux安装Elasticsearch详细教程
Linux安装Elasticsearch详细教程
1505 64
|
7月前
|
JSON 安全 数据可视化
Elasticsearch(es)在Windows系统上的安装与部署(含Kibana)
Kibana 是 Elastic Stack(原 ELK Stack)中的核心数据可视化工具,主要与 Elasticsearch 配合使用,提供强大的数据探索、分析和展示功能。elasticsearch安装在windows上一般是zip文件,解压到对应目录。文件,elasticsearch8.x以上版本是自动开启安全认证的。kibana安装在windows上一般是zip文件,解压到对应目录。elasticsearch的默认端口是9200,访问。默认用户是elastic,密码需要重置。
3776 0
|
存储 安全 数据管理
如何在 Rocky Linux 8 上安装和配置 Elasticsearch
本文详细介绍了在 Rocky Linux 8 上安装和配置 Elasticsearch 的步骤,包括添加仓库、安装 Elasticsearch、配置文件修改、设置内存和文件描述符、启动和验证 Elasticsearch,以及常见问题的解决方法。通过这些步骤,你可以快速搭建起这个强大的分布式搜索和分析引擎。
476 5

热门文章

最新文章