详解SpringCloud微服务技术栈:深入ElasticSearch(1)——数据聚合

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习
🌌上期文章:详解SpringCloud微服务技术栈:ElasticSearch实战(旅游类项目)
📚订阅专栏:微服务技术全家桶
希望文章对你们有所帮助

在之前已经了解了ElasticSearch的基本用法(DSL语句以及RestClient实现),并利用ElasticSearch做了一个旅游类项目加以巩固,现在要进行ElasticSearch更深入的内容,内容包括:

数据聚合:来对海量数据做统计和分析,结合kibana还能形成可视化的图形报表
自动补全:根据用户输入的部分关键字信息去补全关键字
数据同步:先分析MySQL与ElasticSearch的双写一致性问题,并给出对应的解决方案
集群:ES的集群和集群中不同角色的作用,并且搭建一个企业级的高可用的集群

深入ElasticSearch——数据聚合

  • 数据聚合
    • 聚合分类
    • DSL实现Bucket聚合
    • DSL实现Metrics聚合
    • RestClient实现聚合
    • 多条件聚合
    • 带过滤条件的聚合

数据聚合

聚合分类

聚合可以实现对文档数据的统计、分析和运算。常见聚合有3类:
在这里插入图片描述

DSL实现Bucket聚合

现在要统计所有数据中的酒店品牌有几种,此时可以根据酒店品牌的名称做聚合。
MySQL里面直接用group by,而这里需要用Bucket聚合,具体来说是用的term聚合:

# 对价格小于200的做聚合,也可以不限定聚合的范围(不写query)
GET /hotel/_search
{"query": {"range": {"price": {"lte": 200}}},"size": 0, # 设置size=0,表示结果中不包含文档,只包含聚合结果"aggs": { # 定义聚合"brandAgg": { # 给聚合起个名字"terms": { # 聚合的类型,按照品牌,因此选择term"field": "brand", # 参与聚合的字段"size": 20 # 希望获取的聚合结果的数量,默认10}}}
}

DSL实现Metrics聚合

获取每个品牌的用户评分的min、max、avg等值,因此要做聚合的嵌套,在每个bucket中做计算:

GET /hotel/_search
{"size": 0,"aggs": {"brandAgg": {"terms": {"field": "brand","size": 20,"order": { # 做排序,需要指定排序的字段"scoreAgg.avg": "desc"}},"aggs": { # 品牌聚合的自聚合,对每组分别做计算"scoreAgg": { # 聚合名称"stats": { # 聚合类型,stats可以计算min、max、avg"field": "score" # 聚合字段}}}}}
}

RestClient实现聚合

依然是通过DSL语句来写java语句:
在这里插入图片描述
编写测试类:

	@Testvoid testAggregation() throws IOException {//1.准备requestSearchRequest request = new SearchRequest("hotel");//2.准备DSL//2.1 设置size,不需要查看文档,只要看聚合结果request.source().size(0);//2.1 聚合request.source().aggregation(AggregationBuilders.terms("brandAgg") //聚合名称"brandAgg",类型terms.field("brand") //参与聚合的字段.size(10));//3.发出请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);//打印即可查看输出的结构,对照结构来做逐层做解析//System.out.println("response = " + response);//4.解析结果//4.1 获取聚合信息Aggregations aggregations = response.getAggregations();//4.2根据聚合名称获取聚合结果(之前是term类型这里返回的也是term类型)Terms brandTerms = aggregations.get("brandAgg");//4.3获取bucketsList<? extends Terms.Bucket> buckets = brandTerms.getBuckets();//4.4遍历buckets,取出每一个桶(分类)for (Terms.Bucket bucket : buckets) {String key = bucket.getKeyAsString();System.out.println("key = " + key);}}

在这里插入图片描述

多条件聚合

在IUserService接口中定义方法,实现对品牌、城市、星级的聚合(搜索页面的品牌、城市等信息不应该是在页面中写死的,而是通过聚合索引库中的酒店数据得来的)。

例如,我限定了价格的range为100-300,如果杭州不包含这样价位的酒店,那么导航栏上面的城市信息直接就不应该有杭州两个字

IUserService中声明方法:

	/*** 查询城市、星级、品牌的聚合效果* @return 聚合结果,格式:{"城市": {"上海", "北京"}, "品牌": {"如家", "希尔顿"}}*/Map<String, List<String>> filters();

UserService实现方法体:

	@Overridepublic Map<String, List<String>> filters() {try {//1.准备requestSearchRequest request = new SearchRequest("hotel");//2.准备DSL//2.1设置sizerequest.source().size(0);//2.2设置聚合buildAggregation(request);//3.发出请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);//4.解析响应Map<String, List<String>> result = new HashMap<>(); //存放解析后的结果Aggregations aggregations = response.getAggregations();result.put("brand", getAggByName(aggregations, "brandAgg"));result.put("city", getAggByName(aggregations, "cityAgg"));result.put("starName", getAggByName(aggregations, "starAgg"));return result;} catch (IOException e) {throw new RuntimeException(e);}}private List<String> getAggByName(Aggregations aggregations, String aggName) {List<String> list = new ArrayList<>(); //存放每个桶的valueTerms brandTerms = aggregations.get(aggName); //这里返回值不要默认,自行设置为Terms类型的List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();for (Terms.Bucket bucket : buckets) {String key = bucket.getKeyAsString();list.add(key);}return list;}private void buildAggregation(SearchRequest request) {request.source().aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(100));request.source().aggregation(AggregationBuilders.terms("cityAgg").field("city").size(100));request.source().aggregation(AggregationBuilders.terms("starAgg").field("starName").size(100));}

可以在测试类中注入IUserService,调用方法查看运行结果:

	@Resourceprivate IHotelService hotelService;@Testvoid contextLoads() {Map<String, List<String>> filters = hotelService.filters();System.out.println("filters = " + filters);}

在这里插入图片描述

带过滤条件的聚合

聚合已经完成,但是聚合的结果还没有返回到前端,实际上前端页面会向服务端发起请求,查询品牌、城市、星级等字段的聚合结果,我们应当渲染完返还给前端。

查看前端的请求:
在这里插入图片描述
可以看到请求的参数和之前的list里面的是一样,这是因为需要限定一下范围,比如限定了城市为北京,搜索条件为“如家”,那么应该对北京的、名字带“如家”的酒店去做聚合,而不是所有的酒店,这样会大大提高效率。

1、编写controller接口,接受该请求

	@PostMapping("/filters")public Map<String, List<String>> getFilters(@RequestBody RequestParams params){return hotelService.filters(params);}

2、修改IUserService#getFilter()方法,添加RequestParam参数

Map<String, List<String>> filters(RequestParams params);

3、修改getFilters方法的业务,聚合时添加query条件
在这里插入图片描述
至此,数据聚合的实现已经完成。

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

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

相关文章

软件设计不是CRUD(11):低耦合模块设计理论——业务抽象:规划模块分层

上一篇文章《软件设计不是CRUD(10):低耦合模块设计理论——业务抽象:从需求中提取业务维度》本专题详细讲解了业务抽象的一个重要步骤:提取业务维度。本篇文章内容主要讲解在提取业务维度后,如何对应用程序中初步划分的各个功能模块进行分层规划。 1、为什么要进行模块分…

【lesson2】定长内存池的实现

文章目录 介绍定长内存池的设计定长内存池的实现需要成员变量需要的成员函数定长内存池结构定长内存池Delete&#xff08;释放空间&#xff09;的实现定长内存池New&#xff08;申请空间&#xff09;的实现 定长内存池的实现完整版 介绍 作为程序员(C/C)我们知道申请内存使用的…

Zookeeper实现分布式队列

目录 Zookeeper分布式队列 普通方式实现 设计思路 具体实现 使用Curator实现 具体实现 注意事项 Zookeeper分布式队列 常见的消息队列有:RabbitMQ&#xff0c;RocketMQ&#xff0c;Kafka等。Zookeeper作为一个分布式的小文件管理系统&#xff0c;同样能实现简单的队列功…

【python】图形化开发pyqt6基本写法模板与基础控件属性方法整理

pyqt6的简介 首先呢Python有许多可以编写图形化界面的库&#xff0c;我们通常跟着教程的话最初会接触的tkinter&#xff0c;但是学习中会发现编写的图形化跟我们平常接触的软件有很大区别&#xff08;简单来说就是丑&#xff09;。 pyqt则是第三方库&#xff0c;在Python中算…

ETL怎么实现文件处理

在现代企业及各类组织的日常运作中&#xff0c;数据作为一种关键的信息资源&#xff0c;其管理和分析能力直接影响到决策效率与准确性。文件作为数据的主要载体&#xff0c;承载着从运营报告、客户记录、交易明细等各种类型的数据信息。这些海量且多样的文件数据在未经处理的情…

flask_django基于python的城市轨道交通公交线路查询系统vue

同时&#xff0c;随着信息社会的快速发展&#xff0c;城市轨道交通线路查询系统面临着越来越多的信息&#xff0c;因此很难获得他们对高效信息的需求&#xff0c;如何使用方便快捷的方式使查询者在广阔的海洋信息中查询&#xff0c;存储&#xff0c;管理和共享信息方面有效&…

C语言菜鸟入门·运算符(算数运算符,关系运算符,逻辑运算符,位运算符,赋值运算符,三目运算符)详细介绍

目录 ​编辑 1. 算术运算符 2. 关系运算符 3. 逻辑运算符 4. 位运算符 5. 赋值运算符 6. 杂项运算符 ↦ sizeof & 三元 6.1 sizeof&#xff08;&#xff09; 6.2 &取地址运算符 6.3 * 6.4 三目运算符 7. 运算符优先级 运算符是一种告诉编译器执行…

ElementUI组件:Link 文字链接

Link 文字链接 点击下载learnelementuispringboot项目源码 效果图 el-link.vue页面效果图 项目里el-link.vue文件代码 <script> export default {name: el_link }</script> <!--https://element.eleme.cn/#/zh-CN/component/link --> <template>&l…

嵌入式学习第十四天

1.结构体&#xff08;2&#xff09;: &#xff08;1&#xff09;结构体类型定义 &#xff08;2&#xff09;结构体变量的定义 &#xff08;3&#xff09;结构体元素的访问 &#xff08;4&#xff09;结构体的存储: 内存对齐: char 按照1字节对齐 …

C# OpenCvSharp DNN Gaze Estimation 视线估计

目录 介绍 效果 模型信息 项目 代码 frmMain.cs GazeEstimation.cs 下载 C# OpenCvSharp DNN Gaze Estimation 介绍 训练源码地址&#xff1a;https://github.com/deepinsight/insightface/tree/master/reconstruction/gaze 效果 模型信息 Inputs ----------------…

医院安全(不良)事件报告系统源码,不良事件处理的全过程管理,实现11大类不良事件类型的报告上报、流转审批、跟踪改进及统计分析功能。

医院安全&#xff08;不良&#xff09;事件报告系统源码&#xff0c;不良事件上报系统源码&#xff0c;PHP源码 医院安全&#xff08;不良&#xff09;事件报告系统提供11大类不良事件的上报、事件审核处理、时间按分析、事件跟踪与持续改进&#xff0c;事件提醒、权限控制、外…

聊聊DoIP吧

DoIP是啥? DoIP代表"Diagnostic over Internet Protocol",即互联网诊断协议。它是一种用于在车辆诊断中进行通信的网络协议。DoIP的目标是在现代汽车中实现高效的诊断和通信。通过使用互联网协议(IP)作为通信基础,DoIP使得诊断信息能够通过网络进行传输,从而提…

React通用后台模板

一. 项目初始化 1. 创建项目 环境 npm init vite 打开package.json,参考以下各模块版本: "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "react-redux": "^7.2.8", …

Security ❀ TCP异常报文详解

文章目录 1. TCP Out-Of-Order2. TCP Previous Segment Lost3. TCP Retransmission4. TCP Dup Ack XXX#X5. TCP Windows Update6. TCP Previous segment not captured7. 异常案例分析 TCP协议中seq和ack seq的联系&#xff1a; id4的http请求报文由客户端发向服务器&#xff0…

sqli-labs-master靶场训练笔记(1-22|新手村)

2024.1.21 level-1 &#xff08;单引号装饰&#xff09; 先根据提示建立一个get请求 在尝试使用单个单引号测试&#xff0c;成功发现语句未闭合报错 然后反手一个 order by 得到数据库共3列&#xff0c;-- 后面加字母防止浏览器吃掉 -- 操作&#xff08;有些会&#xff09…

maven helper 解决jar包冲突方法

一 概要说明 1.1 说明 首先&#xff0c;解决idea中jar包冲突&#xff0c;使用maven的插件&#xff1a;maven helper插件&#xff0c;它能够给我们罗列出来同一个jar包的不同版本&#xff0c;以及他们的来源&#xff0c;但是对不同jar包中同名的类没有办法。 1.2 依赖顺序 …

Spring | Spring的“数据库开发“ (Srping JDBC)

目录&#xff1a; Spring JDBC1.Spring JDBC的核心类 ( JdbcTemplate类 )2.Srping JDBC 的配置3.JdbcTemplate类的“常用方法”execute( )&#xff1a;直接执行“sql语句”&#xff0c;没有返回值update( ) &#xff1a;“增删改”&#xff0c;返回 “影响的行数”query( ) : “…

双链表的基本知识以及增删查改的实现

满怀热忱&#xff0c;前往梦的彼岸 前言 之前我们对单链表进行了非常细致的剖析&#xff0c;现在我们所面临的则是与之相对应的双链表&#xff0c;我会先告诉诸位它的基本知识&#xff0c;再接着把它的增删查改讲一下&#xff0c;ok&#xff0c;正文开始。 一.链表的种类 我…

其他发现:开源数据可视化分析工具DataEase介绍文档

一、 简介 DataEase 是开源的数据可视化分析工具&#xff0c;帮助用户快速分析数据并洞察业务趋势&#xff0c;从而实现业务的改进与优化。DataEase 支持丰富的数据源连接&#xff0c;能够通过拖拉拽方式快速制作图表&#xff0c;并可以方便地与他人分享。 二、 优势 1、 开…

STM32学习笔记二——STM32时钟源时钟树

目录 STM32芯片内部系统架构详细讲解&#xff1a; 1.芯片内部混乱电信号解决方案&#xff1a; 2.时钟树&#xff1a; 1.内部RC振荡器与外部晶振的选择 2. STM32 时钟源 3.STM32中几个与时钟相关的概念 4.时钟输出的使能及其流程 5.时钟设置的基本流程 时钟源——单片机…