当前位置: 首页 > news >正文

Elasticsearch DSL 中的 aggs 聚合分析

一、聚合的概述

Elasticsearch 的 聚合(Aggregations) 功能用于对数据进行多维分析和统计,支持从简单的指标计算到复杂的分组分析。以下是聚合的基本结构:

{
  "aggs": {                        // 也可以使用"aggregations"
    "agg_name": {                  // 自定义聚合名称
      "agg_type": {                // 聚合类型
        "agg_body": ...            // 聚合体
      }
    }
  }
}

二、聚合的核心类型

Elasticsearch 的聚合分为三大类:

类型功能典型应用
指标聚合(Metric)计算数值型字段的统计值(如平均值、最大值等)平均价格、总销售额、最大值/最小值
桶聚合(Bucket)将文档分组到不同的“桶”中进行统计按类别分组、按时间区间分桶、按范围分桶
管道聚合(Pipeline)对已有聚合结果进行二次计算移动平均值、累计求和、差值计算

三、指标聚合

常见指标聚合有如下:

  1. avg:计算字段的平均值。
  2. sum:计算字段的总和。
  3. max/min:获取字段的最大值/最小值。
  4. stats:一次性返回 count, min, max, avg, sum。
  5. cardinality:统计字段的唯一值数量(近似去重)。
  6. percentiles :计算数值字段中指定百分位数的值。
  7. percentile_ranks:计算给定值在数据集中所处的百分位位置。
  8. top_hits:聚合结果中返回每个分组中最相关或最匹配的文档。
3.1 avg - 平均值
{
  "aggs": {
    "avg_price": {
      "avg": { "field": "price" }
    }
  }	
}
3.2 sum - 求和
{
  "aggs": {
    "total_sales": {
      "sum": { "field": "sales" }
    }
  }
}
3.3 max/min - 最大/最小值
{
  "aggs": {
    "max_age": {
      "max": { "field": "age" }
    }
  }
}
3.4 stats - 基本统计
{
  "aggs": {
    "price_stats": {
      "stats": { "field": "price" }
    }
  }
}
3.5 cardinality - 基数统计(去重计数)
{
  "aggs": {
    "unique_users": {
      "cardinality": { "field": "user_id" }
    }
  }
}
3.6 percentiles - 百分位数
{
  "aggs": {
    "load_time_percentiles": {
      "percentiles": {
        "field": "load_time",
        "percents": [95, 99, 99.9]
      }
    }
  }
}
3.7 percentile_ranks - 百分位排名
{
  "aggs": {
    "load_time_ranks": {
      "percentile_ranks": {
        "field": "load_time",
        "values": [500, 1000]
      }
    }
  }
}
3.8 top_hits - 返回每组顶部文档
{
  "aggs": {
    "top_tags": {
      "terms": { "field": "tags" },
      "aggs": {
        "top_tag_hits": {
          "top_hits": {
            "size": 1,
            "sort": [{ "date": { "order": "desc" } }]
          }
        }
      }
    }
  }
}

四、桶聚合

常见桶聚合有如下:

  1. terms:按字段值分组(类似 SQL 的 GROUP BY)。
  2. date_histogram:按时间区间分桶(如按天、月统计)。
  3. range:按数值范围分桶(如价格区间)。
  4. histogram:按固定间隔分桶(如每 100 为一个区间)。
  5. nested:处理嵌套对象的聚合。
4.1 terms - 按词项分组
{
  "aggs": {
    "genres": {
      "terms": {
        "field": "genre",
        "size": 10,
        "order": { "_count": "desc" }
      }
    }
  }
}
4.2 range - 按范围分组
{
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "to": 50 },
          { "from": 50, "to": 100 },
          { "from": 100 }
        ]
      }
    }
  }
}
4.3 date_range - 日期范围分组
{
  "aggs": {
    "date_ranges": {
      "date_range": {
        "field": "date",
        "format": "yyyy-MM-dd",
        "ranges": [
          { "to": "now-10d/d" },
          { "from": "now-10d/d", "to": "now" },
          { "from": "now" }
        ]
      }
    }
  }
}
4.4 histogram - 直方图
{
  "aggs": {
    "prices": {
      "histogram": {
        "field": "price",
        "interval": 50,
        "extended_bounds": {
          "min": 0,
          "max": 500
        }
      }
    }
  }
}
4.5 nested - 嵌套对象聚合
{
		  "aggs": {
		    "comments": {
		      "nested": { "path": "comments" },
		      "aggs": {
		        "by_user": {
		          "terms": { "field": "comments.user" }
        }
      }
    }
  }
}

五、管道聚合

常见管道聚合有如下:

  1. avg_bucket:计算多个桶的平均值。
  2. cumulative_sum:累计求和。
  3. derivative:计算相邻桶的差值(如环比增长)。
  4. moving_avg:计算移动平均值。
5.1 avg_bucket - 计算桶平均值
{
  "aggs": {
    "sales_per_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "sales": { "sum": { "field": "price" } }
      }
    },
    "avg_monthly_sales": {
      "avg_bucket": {
        "buckets_path": "sales_per_month>sales"
      }
    }
  }
}
5.2 cumulative_sum - 累计和
{
  "aggs": {
    "sales_per_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "sales": { "sum": { "field": "price" } },
        "cumulative_sales": {
          "cumulative_sum": { "buckets_path": "sales" }
        }
      }
    }
  }
}
5.3 derivative - 计算导数
{
  "aggs": {
    "sales_per_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "sales": { "sum": { "field": "price" } },
        "sales_deriv": {
          "derivative": { "buckets_path": "sales" }
        }
      }
    }
  }
}
5.4 moving_avg - 移动平均
{
  "aggs": {
    "sales_per_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "sales": { "sum": { "field": "price" } },
        "moving_avg": {
          "moving_avg": { "buckets_path": "sales" }
        }
      }
    }
  }
}

六、聚合参数优化

  1. 控制返回桶数量

    • size:指定返回的桶数量(默认10)。
      "terms": { "field": "category.keyword", "size": 20 }
      
  2. 过滤空桶

    • min_doc_count:过滤文档数不足的桶。
      "terms": { "field": "category.keyword", "min_doc_count": 5 }
      
  3. 排序桶

    • order:按子聚合结果或文档数排序。
      "terms": { 
        "field": "category.keyword", 
        "order": { "avg_price": "desc" }  // 按平均价格降序
      }
      

七、性能优化建议

  1. 使用 keyword 类型字段分桶:避免对 text 字段直接聚合(需开启 fielddata,性能差)。
  2. 限制聚合范围:结合查询条件减少待聚合数据量。
  3. 避免深度分桶:高基数(唯一值多)字段分桶可能导致内存问题。
  4. 使用近似算法:如 cardinality 聚合的 precision_threshold 参数平衡精度与性能。
  5. 启用 eager_global_ordinals:对高基数字段预加载优化。

八、完整示例

GET /sales/_search
{
  "size": 0,  // 不返回原始文档,仅聚合结果
  "query": {  // 限定只分析 2023 年全年的订单数据(从 2023-01-01 到 2023-12-31)
    "range": { "order_date": { "gte": "2023-01-01", "lte": "2023-12-31" } }
  },
  "aggs": {
    "sales_by_category": {
      "terms": { 
        "field": "category.keyword",  // 按商品类别(category.keyword)分组
        "size": 5,  // 返回销售额最高的 5 个类别
        "order": { "total_sales": "desc" }  // 按每个类别的总销售额(total_sales)降序排列
      },
      "aggs": {
        "total_sales": { "sum": { "field": "sales" } },  // 计算每个类别的销售总额(sum)
        "avg_price": { "avg": { "field": "price" } },  // 计算每个类别的商品平均价格(avg)
        "top_products": {  // 列出每个类别中销量最高的 3 个产品名称
          "terms": { "field": "product_name.keyword", "size": 3 }
        }
      }
    },
    "monthly_trend": {
      "date_histogram": {  // 按月(month)统计销售数据
        "field": "order_date",  // 基于订单日期(order_date)字段
        "calendar_interval": "month"
      },
      "aggs": {
        "monthly_sales": { "sum": { "field": "sales" } },  // 计算每月的销售总额(sum)
        "sales_growth": { "derivative": { "buckets_path": "monthly_sales" } }  // 计算销售额的月度环比增长(derivative)
      }
    }
  }
}
  • 预期返回结果
    1. 按类别统计:
      • 销售额最高的 5 个商品类别
      • 每个类别的总销售额和平均价格
      • 每个类别最畅销的 3 个产品
    2. 按月趋势统计:
      • 2023 年每月的销售总额
      • 每月相比上月的销售额变化(增长/下降)
http://www.dtcms.com/a/121969.html

相关文章:

  • 数据结构实验3.3:求解迷宫路径问题
  • 西门子S7-1500与S7-200SMART通讯全攻略:从基础配置到远程IO集成
  • SQL注入(SQL Injection)
  • Ollama 与 llama.cpp 深度对比
  • [特殊字符]【高并发实战】Java Socket + 线程池实现高性能文件上传服务器(附完整源码)[特殊字符]
  • 虽然理解git命令,但是我选择vscode插件!
  • Databricks: Why did your cluster disappear?
  • 【UE5】RTS游戏的框选功能+行军线效果实现
  • Spring Boot 3.x 下 Spring Security 的执行流程、核心类和原理详解,结合用户描述的关键点展开说明,并以表格总结
  • WPF 绑定方式举例
  • LabVIEW 图像处理中常见的边缘检测算法
  • 发票真伪查验接口集成攻略-PHP批量查验发票真伪
  • 贪心算法(17)(java)可被三整除的最大整数和
  • [CISSP] [9] 安全漏洞,威胁和对策
  • 视觉分析AI赋能智慧水务多场景应用
  • S32K144的m_data_2地址不够存,重新在LD文件中配置地址区域
  • doxygen自动生成文档,注释容易错位的补充
  • 雷电模拟器过检测技术全解析
  • 使用docker 安装向量数据库Milvus
  • 黑马 SpringAI+DeepSeek 实战:从对话机器人到企业级知识库的大模型开发全攻略
  • <《AI大模型应知应会100篇》第8篇:大模型的知识获取方式及其局限性
  • package.json配置项积累
  • 防火墙介绍
  • SpringMvc的请求-获得请求参数
  • 启山智软的营销方法有哪些优势?
  • 大数据(7)Kafka核心原理揭秘:从入门到企业级实战应用
  • 机器学习 Day10 逻辑回归
  • 设计模式 Day 5:夯实观察者模式(Boost 实战精讲)
  • excel中的VBA指令示例(二)
  • 【Java】Java 中不同类型的类详解