elassticsearch8.x-聚合搜索:三种类型的聚合

2025-05-12 21:33

桶聚合:Bucket Aggregations

概念

​ 类比SQL中的groupBy的作用,主要用于统计不同类型数据的数量。

​ 在Elasticsearch中,桶聚合是一种常用的聚合查询操作,它将文档分为多个“桶”,然后在每个桶上进行统计分析。

场景

​ 桶聚合可以用于各种场景,例如: 对数据进行分组统计,比如按照地区、年龄段、性别等字段进行分组统计。

三种类型的聚合

桶聚合:Bucket Aggregations

概念

​ 类比SQL中的groupBy的作用,主要用于统计不同类型数据的数量。

​ 在Elasticsearch中,桶聚合是一种常用的聚合查询操作,它将文档分为多个“桶”,然后在每个桶上进行统计分析。

场景

​ 桶聚合可以用于各种场景,例如: 对数据进行分组统计,比如按照地区、年龄段、性别等字段进行分组统计。

  • 对时间序列数据进行时间段分析,比如按照每小时、每天、每月、每季度、每年等时间段进行分析。

  • 对各种标签信息分类,并统计其数量。

用法

以orders订单索引为例

还包含了一个代码示例,具体是:

GET orders/_search
{
  "aggs": {
    "agg_tag_value_count": { //自定义名称,规范要求看名知其意
      "terms": {
        "field": "tags.keyword" // 注意如果是文本,请使用keyword类型
      }
    }
  }
}

例如:

统计不同总价区间之间的订单数据量

GET orders/_search
{
  "aggs": {
    "range_total_price": { //自定义名称,规范要求看名知其意
      "range":{
        "field": "total_price",
        "ranges": [
          {
           //总价在1000-1100之间的订单数据
            "from": 1000,
            "to":1100
          },
          {
          //总价在1100-1200之间的订单数据
            "from": 1100,
            "to":1200
          },
          {
           //总价在2000之间的订单数据
          	"from":2000
          }
        ]
      }
    }
  }
}

Multi_terms

当在聚合的时候需要对多个字段同时聚合的时候,可以使用multi_terms来完成

GET /<index_name>/_search
{
    "aggs": {
        "agg_name": {
            "multi_terms": {
                "terms": [
                    {
                        "field": "field_1"
                    },
                    {
                        "field": "field_2"
                    }
                ]
            }
        }
    }
}

示例:

根据订单商品的品牌和标签统计

GET orders/_search
{
    "aggs": {
        "band_tags": {
            "multi_terms": {
                "terms": [
                    {
                        "field": "Brand"
                    },
                    {
                        "field": "tags.keyword"
                    }
                ]
            }
        }
    }
}

指标聚合:Metrics Aggregations

场景

用于统计某个指标,如最大值、最小值、平均值,可以结合桶聚合一起使用,如按照商品类型分桶,统计每个桶的平均价格。

品牌

商品类型的订单总价的平均值

订单商品分类的平均值

指标函数

  • 平均值: Avg

  • 最大值: Max

  • 最小值: Min

  • 求和: Sum

  • 详细信息: Stats

  • 数量: Value count

    示例:

GET orders/_search
{
    "aggs": {
        "total_price_max": {
           "max":{
             "field": "total_price"
           }
        },
          "total_price_min": {
           "min":{
             "field": "total_price"
           }
        }
        ,
        "total_price_avg": {
           "avg":{
             "field": "total_price"
           }
        }
    }
}
GET orders/_search
{
    "aggs": {
        "total_price_stats": {
           "stats":{
             "field": "total_price"
           }
        }
    }
}

管道聚合:Pipeline Aggregations

概念

​ 管道聚合用于对聚合的结果进行二次聚合,如要统计绑定数量最多的标签 bucket,就是要先按照标签进行分桶,再在分桶的结果上计算最大值。

场景

用于对聚合查询的二次聚合,如统计订单各商品品牌商品平均价格,即先按照订单商品品牌进行桶聚合,并计算其平均总价,然后对总价计算最大值聚合

语法

GET <index_name>/_search
{
    "aggs": {
        "my_aggs": {
            "<function>": {
                ...
            }
        },
        "aggs": {
            "my_price_bucket": {
                ...
            }
        }
    },
    "my_min_bucket": {
        "<pip_function>": {
            "buckets_path": "my_aggs>price_bucket"
        }
    }
}

示例:

统计订单各商品品牌商品平均价格,即先按照订单商品品牌进行桶聚合,并计算其平均总价,然后对总价计算最大值聚合和最小值聚合

GET orders/_search
{
  "aggs": {
    "agg_pip_total_price": {
      "terms": {
        "field": "Brand"
      },
      "aggs": {
        "avg_total_price": {
          "avg": {
            "field": "total_price"
          }
        }
      }
    },
    "min_avg_total_price": {
      "min_bucket": {
        "buckets_path": "agg_pip_total_price>avg_total_price"
      }
    },
      "max_avg_total_price": {
      "max_bucket": {
        "buckets_path": "agg_pip_total_price>avg_total_price"
      }
    }
  }
}

聚合数据类型

doc values

​ doc values是正排索引的基本数据结构之一,其存在是为了提升排序和聚合效率,默认true,如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,则可以禁用doc values值以节省磁盘空间。

​ 从广义来说,doc values本质上是一个序列化的列式存储。列式存储适用于聚合、排序、脚本等操作,所有的数字、地理坐标、日期、IP和不分词(not_analyzed)字符类型都会默认开启,不支持text和annotated_text类型

PUT sample_doc_values 
{
    "mappings": {
        "properties": {
            "detail_text": {
                "type": "text"
            }
        }
    }
}
//错误示例:如上所说,text类型不支持排序和聚合
GET sample_doc_values/_search
{
    "sort":[
      {
        "detail_text": {
          "order":"desc"
        }
      }
    ]
}


//解决方式:创建一个子字段 类型keyword
delete  sample_doc_values
PUT sample_doc_values 
{
    "mappings": {
        "properties": {
            "detail_text": {
                "type": "text",
                "fields":{
                    "doc_values_detail":{
                        "type":"keyword",
                        "doc_values":true
                    
                    }
                }
            }
        }
    }
}
//利用detail_text的子字段doc_values_detail排序
GET sample_doc_values/_search
{
    "sort":[
      {
        "detail_text.doc_values_detail": { 
          "order":"desc"
        }
      }
    ]
}

fielddata

​ 概念:查询时内存数据结构,在首次用当前字段聚合、排序或者在脚本中使用时,需要字段为fielddata数据结构,并且创建倒排索引保存到堆中。与doc value不同,当没有doc value的字段需要聚合时,需要打开fielddata,然后临时在内存中建立正排索引,fielddata的构建和管理发生在JVM Heap中。Fielddata默认是不启用的,因为text字段比较长,一般只做关键字分词和搜索,很少拿它来进行全文匹配和聚合还有排序。

PUT sample_doc_values 
{
    "mappings": {
        "properties": {
            "detail_text": {
                "type": "text",
                "fields":{
                    "doc_values_detail":{
                        "type":"keyword",
                        
                        "fielddata":true
                    
                    }
                }
            }
        }
    }
}
//利用detail_text的子字段doc_values_detail进行聚合
GET sample_doc_values/_search
{
    "aggs":{
      "sample":{
        "terms":{
          "field": "detail_text.doc_values_detail"
        }
      }
    }
}
相关新闻
热点
投票
查看结果
Tags

站点地图 在线访客: 今日访问量: 昨日访问量: 总访问量:

© 2025 个人网站 版权所有

备案号:苏ICP备2024108837号

苏公网安备32011302322151号