ElasticSearch的DSL查询⑤(ES数据聚合、DSL语法数据聚合、RestClient数据聚合)

目录

一、数据聚合

1.1 DSL实现聚合

1.1.1 Bucket聚合 

1.1.2 带条件聚合

1.1.3 Metric聚合

1.1.4 总结

2.1 RestClient实现聚合

2.1.1 Bucket聚合

2.1.2 带条件聚合

2.2.3 Metric聚合


一、数据聚合

聚合(aggregations)可以让我们极其方便的实现对数据的统计、分析、运算。例如:

  • 什么品牌的手机最受欢迎?

  • 这些手机的平均价格、最高价格、最低价格?

  • 这些手机每月的销售情况如何?

ES实现这些统计功能比数据库的sql要方便的多,而且查询速度非常快,可以实现近实时搜索效果。

聚合常见的有三类:

  • 桶(Bucket)聚合:用来对文档做分组

    • TermAggregation:按照文档字段值分组,例如按照品牌值分组、按照国家分组

    • Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组

  • 度量(Metric)聚合:用来计算一些值,比如:最大值、最小值、平均值等

    • Avg:求平均值

    • Max:求最大值

    • Min:求最小值

    • Stats:同时求maxminavgsum

  • 管道(pipeline)聚合:将其它聚合的结果为基础做进一步做深层次的运算(聚合)

注意:参加聚合的字段必须是keyword、日期、数值、布尔类型 

1.1 DSL实现聚合

与之前的搜索功能类似,我们依然先学习DSL的语法,再学习JavaAPI. 

1.1.1 Bucket聚合 

例如我们要统计所有商品中共有哪些商品分类,其实就是以分类(category)字段对数据分组。category值一样的放在同一组,属于Bucket聚合中的Term聚合。 

基本语法如下: 

# 聚合
GET /goods/_search
{"query": {"match_all": {}}, // 当没有条件(查询所有)的时候可以省略"aggs": { // 定义聚合"cate_agg": { // 给聚合起个名字,随意"terms": { // 聚合类型,terms:词条类型的"field": "category", // 参与聚合的字段"size": 20 // 希望获取聚合结果的数量,默认20}}},"size":0 //在查询过程中不仅仅会把聚合结果返回给我们,同时还会把搜索结果的数据返回给我们,设置size为0,就是不需要返回文档信息。如果不设置size默认为10
}

语法说明:

  • size:在查询过程中不仅仅会把聚合结果返回给我们,同时还会把搜索结果的数据返回给我们,设置size为0,就是不需要返回文档信息。如果不设置size默认为10

  • aggs:定义聚合

    • cate_agg:聚合名称,自定义,但不能重复

      • terms:聚合的类型,按分类聚合,所以用term

        • field:参与聚合的字段名称

        • size:希望返回的聚合结果的最大数量

查询的结果: 

这个就有点类始于Sql语句:select  category,count(*)  from goods group by category

一次可以获取多个聚合:

1.1.2 带条件聚合

默认情况下,Bucket聚合是对索引库的所有文档做聚合,我们可以限定要聚合的文档范围,只要添加query条件即可。

例如,查询价格高于1000元的手机品牌有哪些

我们需要从需求中分析出搜索查询的条件和聚合的目标:

  • 搜索查询条件:

    • 价格高于1000

    • 必须是手机

  • 聚合目标:统计的是品牌,肯定是对brand字段做term聚合

语法如下:

# 聚合
GET /goods/_search
{"query": {"bool": {"filter": [{"term": {"category": "手机"}},{"range": {"price": {"gt": 1000}}}]}},"aggs": {"brand_agg":{"terms": {"field": "brand","size": 20}}},"size":0 
}

聚合结果如下:

可以看到,结果中只剩下1个品牌了。。。

1.1.3 Metric聚合

除了对数据分组(Bucket)以外,我们还可以对每个Bucket内的数据进一步做数据计算和统计。

例如:想知道手机有哪些品牌,每个品牌的价格最小值、最大值、平均值。

语法如下:

# 聚合
GET /goods/_search
{"query": {"bool": {"filter": [{"term": {"category": "手机"}}]}},"aggs": {"brand_agg":{"terms": {"field": "brand","size": 20},"aggs": { // 对品牌分组的结果再进行聚合"price_stats": { // 聚合名称随意"stats": { // 聚合类型:Avg:求平均值,Max:求最大值,Min:求最小值,Stats:同时求max、min、avg、sum。"field": "price" // 要聚合字段}}}}},"size":0 
}

可以看到我们在brand_agg聚合的内部,我们新加了一个aggs参数。这个聚合就是brand_agg的子聚合,会对brand_agg形成的每个桶中的文档分别统计。

  • price_stats:聚合名称

    • stats:聚合类型,stats是metric聚合的一种

      • field:聚合字段,这里选择price,统计价格

由于stats是对brand_agg形成的每个品牌桶内文档分别做统计,因此每个品牌都会统计出自己的价格最小、最大、平均值。 

结果如下:

另外,我们还可以让聚合按照每个品牌的价格平均值排序: 

1.1.4 总结

aggs代表聚合,与query同级,此时query的作用是?

  • 限定聚合的的文档范围

聚合必须的三要素:

  • 聚合名称

  • 聚合类型

  • 聚合字段

聚合可配置属性有:

  • size:指定聚合结果数量

  • order:指定聚合结果排序方式

  • field:指定聚合字段 

2.1 RestClient实现聚合

        可以看到在DSL中,aggs聚合条件与query条件是同一级别,都属于查询JSON参数。因此依然是利用request.source()方法来设置。不过聚合条件的要利用AggregationBuilders这个工具类来构造。

2.1.1 Bucket聚合

DSL与JavaAPI的语法对比如下:

聚合结果解析对比:

完整代码:

    @Testpublic void testAgg() throws IOException {// 1.创建Request对象SearchRequest request = new SearchRequest("goods");// 2.准备请求参数request.source().size(0);// 2.1 聚合参数request.source().aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(5));// 3.发送请求SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);// 4.解析聚合结果Aggregations aggregations = response.getAggregations();// 4.1 获取品牌聚合Terms brandAgg = aggregations.get("brandAgg");// 4.2 获取聚合中的桶List<? extends Terms.Bucket> buckets = brandAgg.getBuckets();// 4.3 遍历桶内数据for (Terms.Bucket bucket : buckets) {// 4.4 获取桶内keySystem.out.println("key = " + bucket.getKeyAsString());System.out.println("count = " + bucket.getDocCount());}}

执行结果:

2.1.2 带条件聚合

例如,查询价格高于1000元的手机品牌有哪些

DSL与JavaAPI的语法对比如下:

Java代码如下:

    @Testpublic void testConditionAgg() throws IOException {// 1.创建Request对象SearchRequest request = new SearchRequest("goods");// 2.准备请求参数BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().filter(QueryBuilders.termQuery("category", "手机")).filter(QueryBuilders.rangeQuery("price").gt(1000));request.source().query(boolQueryBuilder);request.source().size(0);// 2.1 聚合参数request.source().aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(5));// 3.发送请求SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);// 4.解析聚合结果Aggregations aggregations = response.getAggregations();// 4.1 获取品牌聚合Terms brandAgg = aggregations.get("brandAgg");// 4.2 获取聚合中的桶List<? extends Terms.Bucket> buckets = brandAgg.getBuckets();// 4.3 遍历桶内数据for (Terms.Bucket bucket : buckets) {// 4.4 获取桶内keySystem.out.println("key = " + bucket.getKeyAsString());System.out.println("count = " + bucket.getDocCount());}}

执行结果:

可以看到,结果中只剩下1个品牌了。。。

2.2.3 Metric聚合

例如:想知道手机有哪些品牌,每个品牌的价格最小值、最大值、平均值。

DSL与JavaAPI的语法对比如下:

结果解析对比:

完整代码如下:

    @Testpublic void testAgg() throws IOException {// 1.创建Request对象SearchRequest request = new SearchRequest("goods");// 2.准备请求参数BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().filter(QueryBuilders.termQuery("category", "手机"));request.source().query(boolQueryBuilder);request.source().size(0);// 2.1 聚合参数request.source().aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(5).order(// 排序,true:升序(asc),false:降序(desc)BucketOrder.aggregation("priceStats.avg", false) ).subAggregation(AggregationBuilders.stats("priceStats").field("price")));// 3.发送请求SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);// 4.解析聚合结果Aggregations aggregations = response.getAggregations();// 4.1 获取品牌聚合Terms brandAgg = aggregations.get("brandAgg");// 4.2 获取聚合中的桶List<? extends Terms.Bucket> buckets = brandAgg.getBuckets();// 4.3 遍历桶内数据for (Terms.Bucket bucket : buckets) {// 4.4 获取桶内keySystem.out.println("key = " + bucket.getKeyAsString());System.out.println("count = " + bucket.getDocCount());Aggregations subAgg = bucket.getAggregations();Stats priceStats = subAgg.get("priceStats");System.out.println("min = " + priceStats.getMin());System.out.println("max = " + priceStats.getMax());System.out.println("avg = " + priceStats.getAvg());System.out.println("sum = " + priceStats.getSum());}}

执行结果:

 

感谢大家的阅读

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle数据块内部结构详解

文章目录 Oracle数据块详解概述Oracle块具有以下特点&#xff1a;① 最小的I/O单元&#xff1b;② 包含一个或多个OS块&#xff1b;③ 大小由参数DB_BLOCK_SIZE决定&#xff1b;④ 数据库创建时设置&#xff0c;数据库创建后不能更改 Oracle数据块详解 概述 操作系统块是…

音频-语言大模型原理

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

Flutter中自定义气泡框效果的实现

在用户界面的设计中&#xff0c;气泡框&#xff08;Bubble&#xff09;是一种非常有效的视觉工具&#xff0c;它可以用来突出显示信息或提示用户。气泡框广泛应用于聊天应用、通知提示等场景。在 Flutter 中&#xff0c;虽然有很多现成的气泡框组件&#xff0c;但如果你想要更多…

c# checkbox的text文字放到右边

checkbox的text文字放到右边 实现方法如下图 特此记录 anlog 2024年9月2日

[数据集][目标检测]石油泄漏检测数据集VOC+YOLO格式6633张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6633 标注数量(xml文件个数)&#xff1a;6633 标注数量(txt文件个数)&#xff1a;6633 标注…

提前购|基于SSM+vue的创新型产品提前购平台(源码+数据库+文档)

创新型产品提前购平台 基于SSMvue的创新型产品提前购平台 一、前言 二、系统设计 三、系统功能设计 系统功能实现 后台模块实现 管理员模块实现 发布企业管理实现 个体管理实现 投资企业管理实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选…

剪映剪辑影视视频字幕声音批量自动对齐教程

一款智能软件&#xff0c;用它结合剪映或CapCut 你就可以快速将一个视频翻译为另一种语言&#xff0c;非常适合做TikTok中视频的用户&#xff0c;无论是英语区法语区还是日语区&#xff0c;这款名为谷哥剪映助手的软件都能成倍提升你的剪辑效率。 让我来给大家介绍它的使用方法…

C++中的一个标准输出流——cout

目录 开头1.什么是cout?2.C中的一个标准输出流——cout的实际应用打印“Hello, world!”打印大方块打印一个变量 下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我们要学一下关于C中的一个标准输出流——cout的一些知识。 1.什么是cout? cou…

小阿轩yx-Kubernertes日志收集

小阿轩yx-Kubernertes日志收集 前言 在 Kubernetes 集群中如何通过不同的技术栈收集容器的日志&#xff0c;包括程序直接输出到控制台日志、自定义文件日志等 有哪些日志需要收集 日志收集与分析很重要&#xff0c;为了更加方便的处理异常 简单总结一些比较重要的需要收集…

无需更换摄像头,无需施工改造,降低智能化升级成本的智慧工业开源了

智慧工业视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。用户只需在界面上…

ffmpeg 视频编码及基本知识

理论 H264编码原理&#xff08;简略&#xff09; 1. 视频为什么需要进行编码压缩 降低视频数据大小&#xff0c;方便存储和传输 2. 为什么压缩的原始数据采用YUV格式 彩色图像的格式是 RGB 的&#xff0c;但RGB 三个颜色是有相关性的。 采用YUV格式&#xff0c;利用人对图像的…

网络安全入门教程(非常详细)从零基础入门到精通,看完这一篇你就是网络安全高手了。

关于我 我算是“入行”不久的一个新人安全工作者&#xff0c;为什么是引号呢&#xff0c;因为我是个“半个野路子”出身。早在13年的时候&#xff0c;我在初中时期就已经在90sec、wooyun等社区一直学习、报告漏洞。后来由于升学的压力&#xff0c;我逐渐淡出了安全圈子&#x…

攻防世界--->回复 1

开学水题笔记(不是&#xff0c;水题。找点&#xff0c;自信心 T^T )。 下载解压查壳。 32ida打开。 进入main函数。 如下&#xff1a; 关键部分&#xff1a; v5的值未知&#xff0c;说明存在于内存中&#xff0c;直接动调就好了。 DUTCTF{We1c0met0DUTCTF}

综合案例-数据可视化-折线图

一、json数据格式 1.1 json数据格式的定义与功能 json是一种轻量级的数据交互格式&#xff0c;可以按照json指定的格式去组织和封装数据&#xff0c;json数据格式本质上是一个带有特定格式的字符串。 功能&#xff1a;json就是一种在各个编程语言中流通的数据格式&#xff0…

MFC工控项目实例之十一板卡测试信号输入界面

承接专栏《MFC工控项目实例之十添加系统测试对话框》 相关代码 1、在BoardTest.h文件中添加代码 class CBoardTest : public CDialog { // Construction public:CBoardTest(CWnd* pParent NULL); // standard constructorCButtonST m_btnStart[16];CWinThread* pThread…

深入FastAPI:掌握使用多个关联模型的高级用法[Union类型]

在FastAPI中&#xff0c;响应模型可以声明为Union类型&#xff0c;这允许你为同一个端点定义多种可能的响应模型。这种灵活性使得API可以根据不同的情况返回不同类型的数据结构。 例如&#xff0c;根据请求中的查询参数或数据库中的数据&#xff0c;一个API端点可能有时返回一…

数学建模_数据预处理流程(全)

数据预处理整体流程图 一般数据预处理流程 处理缺失值&#xff1a;填补或删除缺失值。处理异常值&#xff1a;检测并处理异常值。数据编码&#xff1a;将分类变量进行标签编码或独热编码。数据标准化/归一化&#xff1a;对数据进行标准化或归一化处理。连续变量离散化&#xff…

微信小程序页面制作——个人信息

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

在Unity环境中使用UTF-8编码

为什么要讨论这个问题 为了避免乱码和更好的跨平台 我刚开始开发时是使用VS开发,Unity自身默认使用UTF-8 without BOM格式,但是在Unity中创建一个脚本,使用VS打开,VS自身默认使用GB2312(它应该是对应了你电脑的window版本默认选取了国标编码,或者是因为一些其他的原因)读取脚本…

代码执行漏洞-Log4j2漏洞 vulhub CVE-2021-44228

步骤一:执行以下命令启动靶场环境并在浏览器访问!!! 查看端口 浏览器访问 可以发现 /solr/admin/cores?action 这⾥有个参数可以传&#xff0c;可以按照上⾯的原理 先构造⼀个请求传过去存在JNDI注⼊那么ldap服务端会执⾏我们传上去的payload JDNI项⽬地址 https://github.com…