理解Es的DSL语法(二):聚合

news2025/4/22 8:42:45

前一篇已经系统介绍过查询语法,详细可直接看上一篇文章(理解DSL语法(一)),本篇主要介绍DSL中的另一部分:聚合

理解Es中的聚合

虽然Elasticsearch 是一个基于 Lucene 的搜索引擎,但也提供了聚合(aggregations)的功能,允许用户对数据进行统计和分析。聚合可以按照不同的维度对数据进行分组和汇总,从而得到有意义的统计信息。这也是Es很多场景下被当作分析工具使用的原因。

聚合语法

使用上来讲,es的聚合就相当于SQL中的group by,在DSL中主要使用aggs关键字和size关键字来控制:

{
  "size":0,
  "aggs":{
    "TestName":{  //自定义的聚合名称
         "term":{ //聚合类型关键字,根据聚合类型来
              "field":"title"  //需要聚合的字段
           }
     }
  }
}

这里着重说一下size关键字,如果单纯进行聚合,而不需要实际数据,最好这里size设置为0,设置size为0在进行聚合时,会默认触发Es的缓存机制,能够很有效的提升性能

当然聚合也可以搭配查询query使用,即对查询的数据进行聚合,例如我们对最近一天的文章,聚合一下标题:

{
  "query":{
     "bool":{
       "filter":[
            {
              "range":{ 
                 "create_time":{
                     "gte":"now - 1d",
                     "lte":"now"
                  }
              }
            }

        ]
    }
  }
  "size":0,
  "aggs":{
    "TestName":{  //自定义的聚合名称
         "term":{ //聚合类型关键字,根据聚合类型来
              "field":"title"  //需要聚合的字段
           }
     }
  }
}

这里Es收到请求后,会先根据query中的条件去检索满足创建时间在近一天内的所有文档,然后对这些文档进行桶聚合,以title字段为桶,将title内容一致的文档放入桶内。

聚合的种类

总的来看,Es的聚合可以分为四类,即Bucketing Aggregations、Metric Aggregations、Matrix Aggregations、Pipeline Aggregations。

Bucketing Aggregations

将数据分桶,类似于 SQL 中的 GROUP BY。例如,可以根据某个字段的不同值将数据分组,然后对每个分组进行统计,对于字段和内容都有一定的限制。

常用的聚合关键字有:

关键字描述适用字段类型
TermsTerms 聚合根据指定字段的确切值将文档分组。它类似于 SQL 中的 GROUP BY 语句。keyword 
Histogram直方图聚合将数值字段划分为指定间隔的桶,并计算每个桶中的文档数量。

数值类型(

integerfloatdouble 、 long)

Date Histogram日期直方图聚合类似于直方图聚合,但它专门用于日期字段,允许你根据时间间隔(如天、周、月等)来分组数据date
Range范围聚合允许你根据指定的范围将数据分组,每个范围定义了上界和下界。数值类型

integerfloatdouble 、 long)

和date
IP Range IP 范围聚合允许你根据 IP 地址的范围将数据分组。ip
Date Range日期范围聚合是范围聚合的日期版本,专门用于日期字段。date
Filter/Filters过滤器聚合根据一个或多个过滤器条件将数据分组,每个过滤器条件定义了一个桶。可以应用于任何类型的字段,但通常与布尔查询结合使用来定义过滤器条件。
Nested 嵌套聚合应用于嵌套字段,它允许你根据嵌套对象中的字段值对嵌套文档进行分组。object或nested

详细的可查阅ElasticSearch的官网,这里仅列出常用的,我们假设Es中存在以下一个数据集合:

[
  {"name": "Book A", "category": "Fiction", "price": 9.99, "publish_date": "2020-01-01"},
  {"name": "Book B", "category": "Science", "price": 15.00, "publish_date": "2021-06-15"},
  {"name": "Book C", "category": "Fiction", "price": 12.50, "publish_date": "2022-03-10"},
  {"name": "Book D", "category": "Education", "price": 8.50, "publish_date": "2019-09-20"},
  {"name": "Book E", "category": "Science", "price": 20.00, "publish_date": "2023-01-05"}
]

并针对该数据集,进行相关的聚合样例:

 Terms Aggregation聚合

查看有多少种category以及每种的文档数量。

示例:

{
   "size":0,
    "aggs": {
        "genres": {
            "terms": {
                "field": "category"  // genre必须为keyword类型
                "size":3         //根据文档数量倒叙展示条数,默认不填写则仅展示10个
            }
        }
    }
}

//输出:
{
  "category": {
    "buckets": [
      {"key": "Fiction", "doc_count": 2},
      {"key": "Science", "doc_count": 2},
      {"key": "Education", "doc_count": 1}
    ]
  }
}
Histogram Aggregation 聚合

按价格区间聚合书籍

{
  "size":0,
  "aggs": {
    "price_distribution": {
      "histogram": {
        "field": "price",
        "interval": 5  //以5元为一个段
      }
    }
  }
}

//输出:
{
  "aggregations": {
    "price_distribution": {
      "buckets": [
        { "key": 5, "doc_count": 1 },
        { "key": 10, "doc_count": 2 },
        { "key": 15, "doc_count": 2 }
      ]
    }
  }
}
Date Histogram Aggregation 聚合

按年份查看出版书籍的数量

{
  "size":0,
  "aggs": {
    "books_over_time": {
      "date_histogram": {
        "field": "publish_date",
        "calendar_interval": "year" //查询区间可以指定单位
      }
    }
  }
}

//输出

{
  "aggregations": {
    "books_over_time": {
      "buckets": [
        { "key_as_string": "2019", "doc_count": 1 },
        { "key_as_string": "2020", "doc_count": 1 },
        { "key_as_string": "2021", "doc_count": 1 },
        { "key_as_string": "2022", "doc_count": 1 },
        { "key_as_string": "2023", "doc_count": 1 }
      ]
    }
  }
}

其中对于date_histogram使用较多,这里单独列一下关于date_histogram的相关参数

  • calendar_interval:按照日历时间间隔(如年、季度、月、周、日等)来创建桶。

  • fixed_interval:按照固定时间间隔(如1小时、5分钟等)来创建桶,不考虑日历界限。

  • min_doc_count:设置为 0 或更大的值,以忽略那些文档计数小于该值的桶。

  • extended_bounds:允许聚合查询返回超出正常查询范围之外的桶,例如在直方图的开始或结束之前添加额外的桶。

  • order:指定桶的排序方式,可以是 asc(升序)或 desc(降序)。

  • format:自定义日期格式,用于指定桶的 key 值的日期格式。

  • time_zone:指定时区来应用到聚合上,特别是对于固定间隔的聚合。

  • pre_zonepost_zone:与 extended_bounds 结合使用,指定额外桶的时区。

{
  "size": 0,
  "aggs": {
    "publish_monthly": {
      "date_histogram": {
        "field": "publish_date",
        "calendar_interval": "month",  // 每月一个桶
        "min_doc_count": 1,            // 只包括至少有一个文档的桶
        "extended_bounds": {
          "min": "2019-01-01",
          "max": "2023-12-31"
        },  // 设置聚合的最小和最大界限
        "order": "desc",              // 桶按降序排序
        "format": "yyyy-MM",          // 桶 key 的格式
        "time_zone": "Europe/Berlin" // 使用柏林时区
      }
    }
  }
}

Range Aggregation聚合

查看价格区间内书籍的数量

{
  "size":0,
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "from": 0, "to": 10 },
          { "from": 10, "to": 20 }
        ]
      }
    }
  }
}

//输出
{
  "aggregations": {
    "price_ranges": {
      "buckets": [
        { "from": 0, "to": 10, "doc_count": 2 },
        { "from": 10, "to": 20, "doc_count": 3 }
      ]
    }
  }
}
Filters Aggregation聚合

同时筛选 Fiction 和 Science 类别的书籍,并分别计算数量。

{
  "size":0,
  "aggs": {
    "category_filters": {
      "filters": {
        "filters": {
          "Fiction": {
            "term": {
              "category.keyword": "Fiction"
            }
          },
          "Science": {
            "term": {
              "category.keyword": "Science"
            }
          }
        }
      }
    }
  }
}
//输出
{
  "aggregations": {
    "category_filters": {
      "buckets": {
        "Fiction": { "doc_count": 2 },
        "Science": { "doc_count": 2 }
      }
    }
  }
}

这里特殊说明一下,针对以上场景,也可以使用:

{
 "query": {
  "bool": {
   "filter": [
     {
      "terms": {
      "category": ["Fiction", "Science"]
     }
    }
   ]
  }
 },
 "size": 0,
 "aggs": {
   "category": {
    "terms": {
      "field": "category"
    }
  }
 }
}

不同的是,使用这种聚合,Es的需要进行两次操作,即:先根据query条件,进行数据查询,再对查询结果进行聚合,而Filters聚合则只有一次操作。在相同场景下,考虑性能的话,使用 filters 聚合可能在某些情况下更有效率,因为它可以利用 Elasticsearch 的缓存机制,特别是当这些特定的过滤条件经常被查询时。

Composite Aggregation聚合

按 category 和 publish_date 的每个月份组合聚合书籍。

{
  "size": 0,
  "aggs": {
    "category_date_composite": {
      "composite": {
        "sources": [
          { "category": { "terms": { "field": "category.keyword" } } },
          { "date": { "date_histogram": { "field": "publish_date", "calendar_interval": "month" } } }
        ],
        "size": 10
      }
    }
  }
}
//输出
{
  "composite_of_category_and_date": {
    "buckets": [
      {"key": {"category": "Fiction", "date": "2020-01"}, "doc_count": 1},
      {"key": {"category": "Fiction", "date": "2022-03"}, "doc_count": 1},
      {"key": {"category": "Science", "date": "2021-06"}, "doc_count": 1},
      {"key": {"category": "Science", "date": "2023-01"}, "doc_count": 1}
    ]
  }
}

Metric Aggregations

对数据进行数学运算,如计算平均值、总和、最小值、最大值等。此类大多对数字类型的字段进行聚合。

关键字描述
Sum Aggregation计算数值字段的总和
Avg Aggregation

计算数值字段的平均值

Min Aggregation

找出数值字段中的最小值

Max Aggregation

找出数值字段中的最大值

Stats Aggregation

返回字段的多个统计度量,包括最小值、最大值、平均值和总和。

Cardinality Aggregation

计算字段中唯一值的近似数量,对于大数据集非常有用,因为它比value_count更高效。

一般配合桶查询使用,对标的是SQL中的SUM、MAX等数学函数

Cardinality Aggregation

查看一共有多少文档:

{
  "size":0,
  "aggs": {
    "countALl": {
      "cardinality": {
        "field": "_id"
      }
    }
  }
}

//输出
{
  "aggregations": {
    "countALl": {
      "value": 3
    }
  }
}

Min/Max Aggregation

//查看书籍最贵的价格
{
  "size":0,
  "aggs": {
    "maximum_price": {
      "max": {
        "field": "price"
      }
    }
  }
}
//输出:
{
  "aggregations": {
    "maximum_price": {
      "value": 20.0
    }
  }
}


//查看书籍最便宜的价格
{
  "size":0,
  "aggs": {
    "min_price": {
      "min": {
        "field": "price"
      }
    }
  }
}
//输出
//输出:
{
  "aggregations": {
    "min_price": {
      "value": 5.0
    }
  }
}

Sum/Avg Aggregation

//对库内书籍价格求和
{
  "aggs": {
    "all_price": {
      "sum": {
        "field": "price"
      }
    }
  }
}

//输出:
{
  "aggregations": {
    "all_price": {
      "value": 13.398
    }
  }
}



//对库内书籍价格求均值
{
  "aggs": {
    "average_price": {
      "avg": {
        "field": "price"
      }
    }
  }
}

//输出
{
  "aggregations": {
    "average_price": {
      "value": 13.398
    }
  }
}

Stats Aggregation

查看价格的综合统计

{
  "size":0,
  "aggs": {
    "price_stats": {
      "stats": {
        "field": "price"
      }
    }
  }
}

//输出:
{
  "aggregations": {
    "price_stats": {
      "count": 5,
      "min": 8.5,
      "max": 20.0,
      "avg": 13.398,
      "sum": 66.99
    }
  }
}

聚合嵌套

语法格式为:

{
  "size":0,
  "aggs":{
      "One":{  // 一层桶名称
         "terms":{
            "field":"fielda"
          },
        "aggs":{  //一层桶下二层聚合
            
          } 
       }
   }
}

以书籍书籍为例,查看每类书籍的平均价格,则可以先对书籍类型进行terms聚合,再在terms桶内,获取桶内书籍的平均价格:

//DSL
{
  "size": 0,
  "aggs": {
    "categories": {
      "terms": {
        "field": "keyword"
      },
      "aggs": {
        "average_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

//输出结果
{
  "aggregations": {
    "categories": {
      "buckets": [
        {
          "key": "Fiction",
          "doc_count": 2,
          "average_price": {
            "value": 11.245
          }
        },
        {
          "key": "Science",
          "doc_count": 2,
          "average_price": {
            "value": 17.5
          }
        },
        {
          "key": "Education",
          "doc_count": 1,
          "average_price": {
            "value": 8.5
          }
        }
      ]
    }
  }
}

也可以查看发布年限,每年里发布书籍的总价格:

{
  "size": 0,
  "aggs": {
    "publish_years": {
      "date_histogram": {
        "field": "publish_date",
        "calendar_interval": "year"
      },
      "aggs": {
        "total_price": {
          "sum": {
            "field": "price"
          }
        }
      }
    }
  }
}

//输出
{
  "aggregations": {
    "publish_years": {
      "buckets": [
        {
          "key_as_string": "2019",
          "key": 1577836800000,
          "doc_count": 1,
          "total_price": {
            "value": 8.5
          }
        },
        {
          "key_as_string": "2020",
          "key": 1609459200000,
          "doc_count": 1,
          "total_price": {
            "value": 9.99
          }
        },
        {
          "key_as_string": "2021",
          "key": 1609459200000,
          "doc_count": 1,
          "total_price": {
            "value": 15.0
          }
        },
        {
          "key_as_string": "2022",
          "key": 1640995200000,
          "doc_count": 1,
          "total_price": {
            "value": 12.5
          }
        },
        {
          "key_as_string": "2023",
          "key": 1672531200000,
          "doc_count": 1,
          "total_price": {
            "value": 20.0
          }
        }
      ]
    }
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1824113.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

单通道触摸感应开关RH6016

1.简介 SOT23-6 RH6016 封装和丝印 RH6016 是一款内置稳压模块的单通道电容式触摸感应控制开关IC,可以替代传统的机械式开关。 RH6016可在有介质(如玻璃、亚克力、塑料、陶瓷等)隔离保护的情况下实现触摸功能,安全性高。 RH6016内置高精度稳压、上电复…

C++17并行算法与HIPSTDPAR

C17 parallel algorithms and HIPSTDPAR — ROCm Blogs (amd.com) C17标准在原有的C标准库中引入了并行算法的概念。像std::transform这样的并行版本算法保持了与常规串行版本相同的签名,只是增加了一个额外的参数来指定使用的执行策略。这种灵活性使得已经使用C标准…

数据采集项目2-业务数据同步

全量同步 每天都将业务数据库中的全部数据同步一份到数据仓库 全量同步采用DataX datax datax使用 执行 python /opt/module/datax/bin/datax.py /opt/module/datax/job/job.json 更多job.json配置文件在: 生成的DataX配置文件 java -jar datax-config-genera…

【RabbitMQ】RabbitMQ 的 6 种工作模式

RabbitMQ 的 6 种工作模式 1.简单模式2.工作队列模式3.交换机模式4.Routing 转发模式5.主题转发模式6.RPC 模式6.1 消息属性6.2 关联标识6.3 工作流程 7.小结 1.简单模式 生产者把消息放入队列,消费者获得消息,如下图所示。这个模式只有 一个消费者、一…

【python】python指南(三):使用正则表达式re提取文本中的http链接

一、引言 对于算法工程师来说,语言从来都不是关键,关键是快速学习以及解决问题的能力。大学的时候参加ACM/ICPC一直使用的是C语言,实习的时候做一个算法策略后台用的是php,毕业后做策略算法开发,因为要用spark&#x…

LeetCode | 520.检测大写字母

这道题直接分3种情况讨论:1、全部都为大写;2、全部都为小写;3、首字母大写其余小写。这里我借用了一个全是大写字母的串和一个全为小写字母的串进行比较 class Solution(object):def detectCapitalUse(self, word):""":type …

Python基础教程(十五):面向对象编程

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 💝&#x1f49…

【机器学习】Dify:AI智能体开发平台版本升级

一、引言 关于dify,之前力推过,大家可以跳转 AI智能体研发之路-工程篇(二):Dify智能体开发平台一键部署了解,今天主要以dify为例,分享一下如何进行版本升级。 二、版本升级 2.1 原方案 #首次…

超图制作栅格数据集专题图示例

之前写过一两篇专题图的博文,是制作的矢量数据集的专题图; 有一个栅格数据集如下,不知是干嘛的,可能是一个地形,或水系; 看一下对栅格数据集制作专题图;能制作的专题图类型少些, 先…

pytorch学习笔记7

getitem在进行索引取值的时候自动调用,也是一个魔法方法,就像列表索引取值那样,一个意思 import torchvision from torch.utils.data import DataLoaderdata_transformtorchvision.transforms.Compose([torchvision.transforms.ToTensor()] ) test_datatorchvision.datasets.C…

GraphQL(9):Spring Boot集成Graphql简单实例

1 安装插件 我这边使用的是IDEA,需要先按照Graphql插件,步骤如下: (1)打开插件管理 在IDEA中,打开主菜单,选择 "File" -> "Settings" (或者使用快捷键 Ctrl Alt S …

【测试】软件测试方案—实际项目直接套用(Word原件)

1. 引言 1.1. 编写目的 1.2. 项目背景 1.3. 读者对象 1.4. 参考资料 1.5. 术语与缩略语 2. 测试策略 2.1. 测试完成标准 2.2. 测试类型 2.2.1. 功能测试 2.2.2. 性能测试 2.2.3. 安全性与访问控制测试 2.3. 测试工具 3. 测试技术 4. 测试资源 4.1. 人员安排 4.2. 测试环境 4.2.…

宝藏速成秘籍(5)插入排序法

一、前言 1.1、概念 插入排序(Insertion Sort)是一种简单直观的排序算法,其工作原理类似于人们整理一手扑克牌。插入排序通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入…

Javaweb03-Servlet技术1(Servlet,ServletConfig,ServletContext)

Servlet技术(Servlet,ServletConfig,ServletContext) 1.Servlet的概述 Servlet是运行在Web服务器端的Java应用程序,它使用Java语言编写。与Java程序的区别是,Servlet 对象主要封装了对HTTP请求的处理,并且它的运行需要Servlet容器(Tomcat)的…

MySQL与PostgreSQL关键对比四(关联查询性能)

引言:MySQL单表的数据规模一般建议在百万级别,而PostgreSQL的单表级别一般可以到亿级,如果是MPP版本就会更多。从基础数据建议上,不难看出,MySQL在Join的情况下也就是主要查询的情况下性能和PostgreSQL相差还是很大的。…

Navicat和SQLynx产品功能比较一(整体比较)

Navicat和SQLynx都是数据库管理工具,在过去的二十年中,国内用户主要是使用Navicat偏多,一般是个人简单开发需要,数据量一般不大,开发相对简单。SQLynx是最近几年的数据库管理工具,Web开发,桌面版…

【odoo】odoo中对子数据的独有操作[(0, 0, {‘name‘: ‘demo‘})]

概要 在Odoo中,有种写法用于操作 one2many 或 many2many 字段时,描述如何在数据库中创建、更新或删除相关记录。具体而言,这是一种命令格式,被称为 "commands" 或 "special command tuples",用于 …

高考志愿填报,大学读什么专业比较好?

高考分数出炉后,选择什么样的专业,如何去选择专业?于毕业生而言是一个难题。因为,就读的专业前景不好,意味着就业情况不乐观,意味着毕业就是失业。 盲目选择专业的确会让自己就业时受挫,也因此…

服务器数据恢复—OceanStor存储中NAS卷数据丢失如何恢复数据?

服务器存储数据恢复环境&故障: 华为OceanStor某型号存储。工作人员在上传数据时发现该存储上一个NAS卷数据丢失,管理员随即关闭系统应用,停止上传数据。这个丢失数据的卷中主要数据类型为office文件、PDF文档、图片文件(JPG、…

Hbase搭建教程

Hbase搭建教程 期待您的关注 ☀小白的Hbase学习笔记 目录 Hbase搭建教程 1.上传hbase的jar包并解压 2.重新登录 3.启动zookeeper 4.配置环境变量 5.关闭ZK的默认配置 6.修改hbase-site.xml文件 7.修改regionservers文件 8.将配置好的文件分发给其它节点 9.配置环境变量…