【Elasticsearch】 Composite Aggregation 详解
1.什么是 Composite Aggregation?
Composite Aggregation 是 Elasticsearch 中的一种特殊聚合方式,适用于需要分页展示的聚合结果。它与传统的聚合方式不同,采用了基于游标的分页模型。这种聚合方式可以高效地处理多级聚合中的所有桶,并支持分页功能。
2.基本结构
一个典型的 Composite Aggregation 查询如下:
```json
GET /your_index_name/_search
{
"size": 0,
"aggs": {
"my_composite_agg": {
"composite": {
"size": 10,
"sources": [
{
"field1": {
"terms": {
"field": "your_field_name1"
}
}
},
{
"field2": {
"terms": {
"field": "your_field_name2"
}
}
}
]
}
}
}
}
```
在上述查询中:
• `sources`定义了按哪些字段分组,字段顺序决定了分组键(bucket key)的生成顺序。
• `size`定义每页的桶数量。
• 响应结果中的`after_key`用于获取下一页数据。
3.分页机制
Composite Aggregation 的分页机制通过`after`参数实现。每次查询返回指定数量的桶,并通过`after_key`提供下一页的游标。这种方式可以确保分页查询中数据无重复、无遗漏。
例如:
```json
GET /your_index_name/_search
{
"size": 0,
"aggs": {
"my_composite_agg": {
"composite": {
"size": 10,
"sources": [
{
"field1": {
"terms": {
"field": "your_field_name1"
}
}
}
],
"after": {
"field1": "last_value_of_field1"
}
}
}
}
}
``
4.排序和方向
Composite Aggregation 支持对每个值源进行排序,可以通过设置`order`参数为`asc`(升序)或`desc`(降序)。
```json
GET /your_index_name/_search
{
"size": 0,
"aggs": {
"my_composite_agg": {
"composite": {
"size": 10,
"sources": [
{
"field1": {
"terms": {
"field": "your_field_name1",
"order": "desc"
}
}
},
{
"field2": {
"terms": {
"field": "your_field_name2",
"order": "asc"
}
}
}
]
}
}
}
}
```
5.处理缺失值
默认情况下,缺少指定字段值的文档会被忽略。通过设置`missing_bucket`参数为`true`,可以将这些文档包含在响应中。
```json
GET /your_index_name/_search
{
"size": 0,
"aggs": {
"my_composite_agg": {
"composite": {
"size": 10,
"sources": [
{
"field1": {
"terms": {
"field": "your_field_name1",
"missing_bucket": true
}
}
}
]
}
}
}
}
```
6.性能优化
Composite Aggregation 的设计特别适合大规模数据的聚合和分页,是传统`from + size`分页方法的高效替代方案。为了进一步优化性能,建议在索引中设置索引排序,使其与复合聚合中的源顺序部分或完全匹配。
7.应用场景
Composite Aggregation 适用于以下场景:
• 需要分页展示聚合结果。
• 处理大规模数据时,需要高效分页和排序。
• 需要对多个字段进行分组和聚合。
通过上述特性,Composite Aggregation 提供了一种强大且灵活的方式来处理复杂的聚合需求,特别是在需要分页和排序的场景中表现出色。
好的,下面我将通过一个具体的例子来展示如何使用 Composite Aggregation 来实现分页聚合查询。假设我们有一个电商数据集,其中包含商品的销售记录,我们希望按日期和商品类别进行分组,并计算每个分组的销售总额。
数据示例
假设我们的索引名为`sales`,其中的文档如下:
```json
{
"timestamp": "2024-01-01T00:00:00Z",
"product": "T-shirt",
"category": "Clothing",
"price": 20
}
{
"timestamp": "2024-01-01T00:00:00Z",
"product": "Jeans",
"category": "Clothing",
"price": 40
}
{
"timestamp": "2024-01-02T00:00:00Z",
"product": "T-shirt",
"category": "Clothing",
"price": 20
}
{
"timestamp": "2024-01-02T00:00:00Z",
"product": "Laptop",
"category": "Electronics",
"price": 1000
}
```
查询目标
我们希望按日期和商品类别进行分组,并计算每个分组的销售总额。同时,我们希望分页显示结果,每页显示 2 个分组。
第一页查询
首先,我们查询第一页的结果:
```json
GET /sales/_search
{
"size": 0,
"aggs": {
"sales_by_date_and_category": {
"composite": {
"size": 2,
"sources": [
{
"date": {
"date_histogram": {
"field": "timestamp",
"calendar_interval": "1d"
}
}
},
{
"category": {
"terms": {
"field": "category"
}
}
}
]
},
"aggregations": {
"total_sales": {
"sum": {
"field": "price"
}
}
}
}
}
}
```
解释
• `size`:每页返回的分组数量。
• `sources`:定义了两个分组字段:
• `date`:按日期分组,每天一个桶。
• `category`:按商品类别分组。
• `aggregations`:在每个复合桶中计算销售总额。
查询结果
返回的结果如下:
```json
{
"aggregations": {
"sales_by_date_and_category": {
"after_key": {
"date": 1704115200000,
"category": "Clothing"
},
"buckets": [
{
"key": {
"date": 1704028800000,
"category": "Clothing"
},
"doc_count": 2,
"total_sales": {
"value": 60
}
},
{
"key": {
"date": 1704115200000,
"category": "Clothing"
},
"doc_count": 1,
"total_sales": {
"value": 20
}
}
]
}
}
}
```
解释
• `buckets`:包含两个分组:
• 第一个分组:`2024-01-01`的`Clothing`类别,销售总额为 60。
• 第二个分组:`2024-01-02`的`Clothing`类别,销售总额为 20。
• `after_key`:提供了下一页的游标。
第二页查询
使用`after_key`查询下一页的结果:
```json
GET /sales/_search
{
"size": 0,
"aggs": {
"sales_by_date_and_category": {
"composite": {
"size": 2,
"sources": [
{
"date": {
"date_histogram": {
"field": "timestamp",
"calendar_interval": "1d"
}
}
},
{
"category": {
"terms": {
"field": "category"
}
}
}
],
"after": {
"date": 1704115200000,
"category": "Clothing"
}
},
"aggregations": {
"total_sales": {
"sum": {
"field": "price"
}
}
}
}
}
}
``
查询结果
返回的结果如下:
```json
{
"aggregations": {
"sales_by_date_and_category": {
"after_key": {
"date": 1704115200000,
"category": "Electronics"
},
"buckets": [
{
"key": {
"date": 1704115200000,
"category": "Electronics"
},
"doc_count": 1,
"total_sales": {
"value": 1000
}
}
]
}
}
}
``
解释
• `buckets`:包含一个分组:
• `2024-01-02`的`Electronics`类别,销售总额为 1000。
• `after_key`:提供了下一页的游标。
通过这种方式,我们可以高效地分页查询聚合结果,而不会遗漏或重复任何数据。
好的,接下来我们继续探讨如何处理更多分页结果,以及如何优化和扩展这个查询。
继续分页查询
假设我们继续查询下一页,使用上一页返回的`after_key`:
```json
GET /sales/_search
{
"size": 0,
"aggs": {
"sales_by_date_and_category": {
"composite": {
"size": 2,
"sources": [
{
"date": {
"date_histogram": {
"field": "timestamp",
"calendar_interval": "1d"
}
}
},
{
"category": {
"terms": {
"field": "category"
}
}
}
],
"after": {
"date": 1704115200000,
"category": "Electronics"
}
},
"aggregations": {
"total_sales": {
"sum": {
"field": "price"
}
}
}
}
}
}
```
查询结果
如果返回结果为空,说明已经到达最后一页:
```json
{
"aggregations": {
"sales_by_date_and_category": {
"buckets": []
}
}
}
``
这表明所有分组已经查询完毕。
性能优化
为了进一步优化性能,可以考虑以下几点:
1. 设置合理的`size`参数:根据实际需求设置合适的分页大小,避免过大或过小。
2. 索引排序:如果数据量很大,可以在索引创建时设置索引排序,使其与聚合的字段顺序一致。例如:
```json
PUT /sales
{
"settings": {
"index": {
"sort.field": ["timestamp", "category"],
"sort.order": ["asc", "asc"]
}
}
}
```
3. 禁用`track_total_hits`:在分页查询中,通常不需要统计总命中数,可以通过设置`track_total_hits: false`来节省资源。
扩展应用
Composite Aggregation 不仅可以用于分页查询,还可以结合其他聚合功能,例如:
• 计算平均值:在每个分组中计算平均销售额。
```json
"aggregations": {
"average_sales": {
"avg": {
"field": "price"
}
}
}
```
• 多级分组:可以增加更多分组字段,例如按地区分组。
```json
"sources": [
{
"date": {
"date_histogram": {
"field": "timestamp",
"calendar_interval": "1d"
}
}
},
{
"category": {
"terms": {
"field": "category"
}
}
},
{
"region": {
"terms": {
"field": "region"
}
}
}
]
```
总结
通过 Composite Aggregation,我们可以高效地实现分页聚合查询,避免了传统分页方法(如`from + size`)在大规模数据下的性能瓶颈。同时,它还支持灵活的排序、多级分组和子聚合功能,能够满足复杂的业务需求。
以下是使用`composite aggregation`结合`terms`、`histogram`、`date_histogram`和`geotile_grid`的示例:
1.`terms`类型的`composite aggregation`
以下示例对`authors`索引中的`author_name`字段进行`terms`聚合:
```json
GET authors/_search
{
"size": 0,
"aggs": {
"our_buckets": {
"composite": {
"sources": [
{ "authors": { "terms": { "field": "author_name" } } }
]
}
}
}
}
```
2.`histogram`类型的`composite aggregation`
以下示例对`authors`索引中的`books_number`字段进行`histogram`聚合,区间设置为5:
```json
GET authors/_search
{
"size": 0,
"aggs": {
"our_buckets": {
"composite": {
"sources": [
{ "booksnum": { "histogram": { "field": "books_number", "interval": 5 } } }
]
}
}
}
}
```
3.`date_histogram`类型的`composite aggregation`
以下示例对`books`索引中的`publish_date`字段进行`date_histogram`聚合,时间间隔设置为一周:
```json
GET books/_search
{
"size": 0,
"aggs": {
"our_buckets": {
"composite": {
"sources": [
{ "week": { "date_histogram": { "field": "publish_date", "calendar_interval": "1w" } } }
]
}
}
}
}
```
4.`geotile_grid`类型的`composite aggregation`
以下示例对`authors`索引中的`authors_location`字段进行`geotile_grid`聚合,精度设置为6:
```json
GET authors/_search
{
"size": 0,
"aggs": {
"our_buckets": {
"composite": {
"sources": [
{ "authorsloc": { "geotile_grid": { "field": "authors_location", "precision": 6 } } }
]
}
}
}
}
```
5.组合使用多种聚合类型
以下示例同时使用`date_histogram`和`terms`聚合:
```json
GET books/_search
{
"size": 0,
"aggs": {
"our_buckets": {
"composite": {
"sources": [
{ "week": { "date_histogram": { "field": "publish_date", "calendar_interval": "1w" } } },
{ "authors": { "terms": { "field": "author_name" } } }
]
}
}
}
}
```
这些示例展示了如何在`composite aggregation`中使用不同类型的聚合,以满足不同的数据分析需求。
相关文章:

【Elasticsearch】 Composite Aggregation 详解
1.什么是 Composite Aggregation? Composite Aggregation 是 Elasticsearch 中的一种特殊聚合方式,适用于需要分页展示的聚合结果。它与传统的聚合方式不同,采用了基于游标的分页模型。这种聚合方式可以高效地处理多级聚合中的所有桶&#x…...

如何通过 Logstash 将数据采集到 Elasticsearch
作者:来自 Elastic Andre Luiz 将 Logstash 与 Elasticsearch 集成以实现高效的数据提取、索引和搜索的分步指南。 什么是 Logstash? Logstash 是一种广泛使用的 Elastic Stack 工具,用于实时处理大量日志数据。它充当高效的数据管道&#x…...

mysql的cpu使用率100%问题排查
背景 线上mysql服务器经常性出现cpu使用率100%的告警, 因此整理一下排查该问题的常规流程。 1. 确认CPU占用来源 检查系统进程 使用 top 或 htop 命令,确认是否是 mysqld 进程导致CPU满载:top -c -p $(pgrep mysqld)2. 实时分析MySQL活动 …...

centos虚拟机迁移没有ip的问题
故事背景,我们的centos虚拟机本来是好好的,但是拷贝到其他电脑上就不能分配ip,我个人觉得这个vmware他们软件应该搞定这个啊,因为这个问题是每次都会出现的。 网络选桥接 网络启动失败 service network restart Restarting netw…...

接入 deepseek 实现AI智能问诊
1. 准备工作 注册 DeepSeek 账号 前往 DeepSeek 官网 注册账号并获取 API Key。 创建 UniApp 项目 使用 HBuilderX 创建一个新的 UniApp 项目(选择 Vue3 或 Vue2 模板)。 安装依赖 如果需要在 UniApp 中使用 HTTP 请求,推荐使用 uni.requ…...

用AVFrame + AVPacket 完成accede编码和直接用ffmpeg命令行实现acc编码的对比
在使用 FFmpeg 进行 AAC 音频编码时,可以选择两种方式:通过编程接口(如 AVFrame 和 AVPacket)实现 AAC 编码,或者直接使用 FFmpeg 命令行工具。这两种方式各有特点,适用于不同的场景。以下是对两种方法的详细分析,包括它们的区别、优缺点以及适用场景。 一、通过 AVFram…...

计算机网络笔记再战——理解几个经典的协议6——TCP与UDP
目录 先说端口号 TCP 使用序号保证顺序性和应答来保证有效性 超时重传机制 TCP窗口机制 UDP 路由协议 协议分类:IGP和EGP 几个经典的路由算法 RIP OSPF 链路状态数据库(LSDB) LSA(Link State Advertisement࿰…...

【AI】在Ubuntu中使用docker对DeepSeek的部署与使用
这篇文章前言是我基于部署好的deepseek-r1:8b模型跑出来的 关于部署DeepSeek的前言与介绍 在当今快速发展的技术环境中,有效地利用机器学习工具来解决问题变得越来越重要。今天,我将引入一个名为DeepSeek 的工具,它作为一种强大的搜索引擎&a…...

openssl使用
openssl使用 提取密钥对 数字证书pfx包含公钥和私钥,而cer证书只包含公钥。提取需输入证书保护密码 openssl pkcs12 -in xxx.pfx -nocerts -nodes -out pare.key提取私钥 openssl rsa -in pare.key -out pri.key提取公钥 openssl rsa -in pare.key -pubout -ou…...

《语义捕捉全解析:从“我爱自然语言处理”到嵌入向量的全过程》
首先讲在前面,介绍一些背景 RAG(Retrieval-Augmented Generation,检索增强生成) 是一种结合了信息检索与语言生成模型的技术,通过从外部知识库中检索相关信息,并将其作为提示输入给大型语言模型ÿ…...

HIVE如何注册UDF函数
如果注册UDF函数的时候报了上面的错误,说明hdfs上传的路径不正确, 一定要用下面的命令 hadoop fs -put /tmp/hive/111.jar /user/hive/warehouse 一定要上传到上面路径,这样在创建函数时,引用下面的地址就可以创建成功...

VsCode创建VUE项目
1. 首先安装Node.js和npm 通过网盘分享的文件:vsCode和Node(本人电脑Win11安装) 链接: https://pan.baidu.com/s/151gBWTFZh9qIDS9XWMJVUA 提取码: 1234 它们是运行和构建Vue.js应用程序所必需的。 1.1 Node安装,点击下一步即可 …...

x64、aarch64、arm与RISC-V64:详解四种处理器架构
x64、aarch64、arm与RISC-V64:详解四种处理器架构 x64架构aarch64架构ARM架构RISC-V64架构总结与展望在计算机科学领域,处理器架构是构建计算机系统的基石,它决定了计算机如何执行指令、管理内存和处理数据。x64、aarch64、arm与RISC-V64是当前主流的四种处理器架构,它们在…...

如何使用iframe来渲染ThingsBoard仪表盘
1、概述 当我们在使用ThingsBoard的时候,有时候需要再自己的前端项目中展示大屏,thingsboard的仪表盘是可以来做大屏的,虽然界面达不到非常的美观,但是对比之前的版本,现在的版本仪表盘做了很多的优化了。可以实现将thingsboard的仪表板嵌入到自己的vue界面中作为大屏显示…...

退格法记单词(类似甘特图)
退格法记单词,根据记忆次数或熟练程度退格,以示区分,该方法用于短时高频大量记单词: explosion爆炸,激增 mosquito蚊子granary粮仓,谷仓 offhand漫不经心的 transient短暂的slob懒惰而邋遢的…...

计算 MySQL 表行的成本是多少?
当计算表中的所有行时,将使用什么索引?好吧,MySQL文档文档对此提供了一个直接的答案,引用: InnoDB 通过遍历最小的可用二级索引来处理 SELECT COUNT(*) 语句除非索引或优化器提示指示优化器使用…...

Pygame介绍与游戏开发
提供pygame功能介绍的文档:Pygame Front Page — pygame v2.6.0 documentation 基础语法和实现逻辑 与CLI不同,pygame提供了图形化使用界面GUI(graphical user interface)基于图像的界面可以创建一个有图像和颜色的窗口 要让py…...

webpack配置方式
1. 基本配置文件 (webpack.config.js)(导出一个对象) 最常见的方式是通过 webpack.config.js 文件来配置 Webpack,导出一个对象。你可以在这个文件中导出一个配置对象,指定入口、输出、加载器、插件等。 // webpack.config.js m…...

10. k8s二进制集群之Kube Scheduler部署
在开始之前需要准备什么?创建kube-scheduler证书请求文件【即证书的生成⓵】根据上面证书配置文件生成kube-scheduler证书【即证书的生成⓶】创建与关联kube-scheduler配置文件(为后面生成系统服务做准备)创建kube-scheduler服务配置文件【准备系统服务⓵】创建kube-schedul…...

java实现8583报文解析技术详解
文章目录 概要整体架构流程技术名词解释技术细节小结概要 ISO 8583协议是金融交易系统中广泛使用的通信协议,用于规范报文的格式和数据交换。解析8583报文是实现金融交易系统的关键技术之一。本文将详细介绍8583报文解析的核心实现,重点关注解析算法和关键代码逻辑。 8583报…...

k8s服务发现有哪些方式?
在 Kubernetes 中,服务发现是指如何让应用程序在集群内互相找到并通信。Kubernetes 提供了多种服务发现的方式,适应不同的使用场景。以下是 Kubernetes 中常见的服务发现方式: 1. 环境变量(Environment Variables) 概…...

【SqlServer】SQL Server Management Studio (SSMS) 下载、安装、配置使用及卸载——保姆级教程
超详细的 SQL Server Management Studio (SSMS) 下载、安装、连接数据库配置及卸载教程 SQL Server Management Studio (SSMS) 是微软提供的图形化管理工具,主要用于连接、管理和开发 SQL Server 数据库。以下是详细的 SSMS 下载、安装、连接数据库以及卸载的完整教…...

[ESP32:Vscode+PlatformIO]添加第三方库 开源库 与Arduino导入第三方库的区别
前言 PlatformIO与Arduino在添加第三方库方面的原理存在显著差异 在PlatformIO中,第三方库的使用是基于项目(工程)的。具体而言,只有当你为一个特定的项目添加了某个第三方库后,该项目才能使用该库。这些第三方库的文…...

音频文件格式——AAC、OGG和FLAC
3.AAC文件格式 3.1 封装格式解析 高级音频编码 (Advanced Audio Coding) 是一种用于有损数字音频压缩的音频编码标准。它被设计为 MP3 格式的继承者,在相同比特率下通常可以获得比 MP3 更高的音质。AAC有两种封装格式: ADIF&am…...

BUU26 [极客大挑战 2019]HardSQL1
输入一些SQL关键词,发现空格,,union,and,by都被过滤了 被过滤,就用like替代 发现登录成功,可以注入 报错注入 注意 1.这里过滤了空格,就用()将内容包裹起来 比如说:…...

多光谱成像技术在华为Mate70系列的应用
华为Mate70系列搭载了光谱技术的产物——红枫原色摄像头,这是一款150万像素的多光谱摄像头。 相较于普通摄像头,它具有以下优势: 色彩还原度高:色彩还原准确度提升约 120%,能捕捉更多光谱信息,使拍摄照片色…...

借助 Cursor 快速实现小程序前端开发
借助 Cursor 快速实现小程序前端开发 在当今快节奏的互联网时代,小程序因其便捷性、高效性以及无需下载安装的特点,成为众多企业和开发者关注的焦点。然而,小程序的开发往往需要耗费大量的时间和精力,尤其是在前端开发阶段。幸运…...

【deepseek】ollama chatbox webui 本地部署deepseek 踩坑记录
部署 1、前往Ollama官网下载跨平台工具 官网直达:https://ollama.com/download 2、挑选适合自己设备的模型版本,获取运行指令 访问模型库:https://ollama.com/library/deepseek-r1 ▌配置建议: • 入门级:1.5B版本&…...

在离线的服务器上部署Python的安装库
在离线服务器上部署 Python 安装库(如 SQLAlchemy、pandas、pyodbc 等),可以使用以下方法: 方法 1:在联网机器上下载依赖,拷贝到离线服务器 适用于:服务器完全无法访问互联网。 步骤 1. 在联网…...

计算机网络笔记再战——理解几个经典的协议2
理解互联网与TCP/IP 下面,我们将会开始理解互联网这个东西,进一步的,我们会理解何为TCP/IP 我们的互联网就是一个巨大的网状结构,需要注意的是——每一个网状的节点之间都是使用一个叫做NOC,Network Operation Center…...