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可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
存储 搜索推荐 Java
|
3月前
|
SQL JSON API
ELK技术栈 - Elasticsearch 学习笔记(三)
ELK技术栈 - Elasticsearch 学习笔记(三)
41 0
|
3月前
|
存储 SQL Java
聚合在Elasticsearch中的使用及示例验证
聚合在Elasticsearch中的使用及示例验证
71 0
|
3月前
|
测试技术 定位技术 API
万字长文:一文彻底搞懂Elasticsearch中Geo数据类型查询、聚合、排序
万字长文:一文彻底搞懂Elasticsearch中Geo数据类型查询、聚合、排序
94620 140
|
3月前
|
iOS开发 索引 MacOS
Elasticsearch 聚合字段aggregate-metric-double
Elasticsearch 聚合字段aggregate-metric-double
23 0
|
3月前
|
缓存 Java API
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——聚合与搜索(三)
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——聚合与搜索(三)
|
3月前
|
存储 JSON API
ELK技术栈 - Elasticsearch 学习笔记(二)
ELK技术栈 - Elasticsearch 学习笔记(二)
206 0
|
3月前
|
存储 SQL JSON
ELK技术栈 - Elasticsearch 学习笔记(一)
ELK技术栈 - Elasticsearch 学习笔记(一)
181 0
|
5月前
|
JSON 自然语言处理 开发工具
elasticsearch7.X学习笔记
elasticsearch7.X学习笔记
|
5月前
|
数据库 Python
Python-ElasticSearch客户端的封装(聚合查询、统计查询、全量数据)
Python-ElasticSearch客户端的封装(聚合查询、统计查询、全量数据)
56 0

热门文章

最新文章