集成ES分组查询统计求平均值

前言

       之前其实写过ES查询数据,进行分组聚合统计:
复杂聚合分组统计实现


一、目标场景

  1. 机房机柜的物联网设备上传环境数据,会存储到ES
  2. 存到ES的温湿度数据需要查询,进行分组后,再聚合统计求平均值

二、使用步骤

1.引入库

       我这里因为ES服务已经升级到8.0.0了,然后ES数据查询分组,我这里需要对时间进行格式化,再聚合avg,所以客户端相关版本用的7.17.4

<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>7.17.4</version><exclusions><exclusion><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.17.4</version><exclusions><exclusion><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId></exclusion></exclusions>
</dependency><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.17.4</version>
</dependency>

2.配置类

       目前我们就是单服务的,这个配置类够用了。其实我配置类就是要把RestHighLevelClient注入,并交给spring管理。

/*** ES配置类* @author zwmac*/
@Configuration
@Data
public class ElasticSearchConfig {@Value("${es.host}")private String host;@Value("${es.port}")private int port;@Value("${es.username}")private String loginName;@Value("${es.password}")private String password;private RestHighLevelClient client;@Beanpublic RestHighLevelClient client() {final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials(loginName, password));HttpHost[] httpHostArray = new HttpHost[1];httpHostArray[0] = new HttpHost(host, port);RestClientBuilder restClientBuilder = RestClient.builder(httpHostArray).setHttpClientConfigCallback(httpClientBuilder -> {httpClientBuilder.disableAuthCaching();return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);});restClientBuilder.setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder.setConnectTimeout(60000).setSocketTimeout(150000));client = new RestHighLevelClient(restClientBuilder);return client;}
}

3.使用

@Resourceprivate RestHighLevelClient restHighLevelClient;/*** 查询温湿度24小时平均值* @param deviceCode 设备编码* @param startTime 开始时间* @param endTime 结束时间* @param humName 湿度字段名* @param tempName 温度字段名* @return 温湿度24小时平均值*/private TreeMap<String, Map<String, Double>> queryTempHumDayAvg(String deviceCode, Date startTime, Date endTime, String humName, String tempName) {TreeMap<String, Map<String, Double>> treeMap = new TreeMap<>();//ES查询String index = EsCalendar.getDeviceFlowIndex(startTime, endTime);SearchRequest searchRequest = new SearchRequest(index);SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//忽略不可用索引,允许索引不不存在,通配符表达式将扩展为打开的索引searchRequest.indicesOptions(IndicesOptions.fromOptions(true, true, true, false));String timeFmt = "yyyy-MM-dd";// 组装ES请求数据String startTimeStr = DateUtil.format(startTime, DatePattern.NORM_DATETIME_PATTERN);String endTimeStr = DateUtil.format(endTime, DatePattern.NORM_DATETIME_PATTERN);QueryBuilder rangeQuery = QueryBuilders.rangeQuery("createTime").lte(endTimeStr).gte(startTimeStr);BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();// 必须为deviceCodeboolQueryBuilder.must(QueryBuilders.termQuery("deviceCode", deviceCode));rangeQuery = QueryBuilders.boolQuery().must(rangeQuery).must(boolQueryBuilder);QueryBuilder boolQuery = QueryBuilders.boolQuery().must(rangeQuery);searchSourceBuilder.query(boolQuery).size(0);//平均值 温度//String tempName = "temp_avg";String tempAvgName = tempName + "_avg";String tempFactorName = "data." + tempName;AvgAggregationBuilder tempAvgAggregationBuilder = AggregationBuilders.avg(tempAvgName).field(tempFactorName);//平均值 湿度//String humName = "hygrometer_avg";String humAvgName = humName + "_avg";String humFactorName = "data." + humName;AvgAggregationBuilder humAvgAggregationBuilder = AggregationBuilders.avg(humAvgName).field(humFactorName);String createTimeGroup = "createTimeGroup";DateHistogramAggregationBuilder aggregation = AggregationBuilders.dateHistogram(createTimeGroup).field("createTime").fixedInterval(DateHistogramInterval.DAY).format(timeFmt)//过滤掉count为0的数据.minDocCount(1).subAggregation(tempAvgAggregationBuilder).subAggregation(humAvgAggregationBuilder);//分组条件searchSourceBuilder.aggregation(aggregation);searchRequest.source(searchSourceBuilder);// 按照因子列表查询searchRequest.source(searchSourceBuilder);SearchResponse searchResponse = null;Map<String, Map<String, Double>> mp = new HashMap<>();try {log.info("方法getCabinetTempHum24HourAvg查询ES请求数据:" + searchRequest);searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);log.info("方法getCabinetTempHum24HourAvg查询ES响应数据:" + searchResponse.toString());Aggregations aggregations = searchResponse.getAggregations();if (aggregations != null) {//组织出参数aggregations.forEach(agg -> {ParsedDateHistogram parsedDateHistogram = (ParsedDateHistogram) agg;List buckets = parsedDateHistogram.getBuckets();if (CollectionUtil.isNotEmpty(buckets)) {buckets.forEach(bucket -> {ParsedDateHistogram.ParsedBucket timeGroupTerm = (ParsedDateHistogram.ParsedBucket) bucket;String timeStr = timeGroupTerm.getKeyAsString();Aggregations subAggregations = timeGroupTerm.getAggregations();if (subAggregations != null) {Map<String, Double> tempHumMap = new HashMap<>();Map<String, Aggregation> subAggMap = subAggregations.asMap();if (subAggMap != null) {Aggregation tempAgg = subAggMap.get(tempAvgName);if (tempAgg != null) {ParsedAvg tempAggPdh = (ParsedAvg) tempAgg;tempHumMap.put(tempName, tempAggPdh.getValue());}Aggregation humAgg = subAggMap.get(humAvgName);if (humAgg != null) {ParsedAvg humAggPdh = (ParsedAvg) humAgg;tempHumMap.put(humName, humAggPdh.getValue());}}mp.put(timeStr, tempHumMap);}});}});}//数据补全List<DateTime> dateTimeList = DateUtil.rangeToList(startTime, DateUtil.offsetHour(endTime, -1), DateField.HOUR_OF_DAY);if (CollectionUtil.isNotEmpty(dateTimeList)) {String finTempName = "temp_avg";String finHumName = "hum_avg";dateTimeList.forEach(dateTime -> {String timeStr = DateUtil.format(dateTime, timeFmt);Map<String, Double> finTempHumMap = new HashMap<>();Map<String, Double> tempHumMap = mp.get(timeStr);if (tempHumMap == null) {finTempHumMap.put(finTempName, 0.0);finTempHumMap.put(finHumName, 0.0);} else {Double tempAvg = tempHumMap.get(tempName);Double humAvg = tempHumMap.get(humName);finTempHumMap.put(finTempName, tempAvg);finTempHumMap.put(finHumName, humAvg);}treeMap.put(timeStr, finTempHumMap);});}} catch (Exception e) {log.error("方法countByEs查询ES异常", e);}return treeMap;}

关键点注意:

  1. QueryBuilders.rangeQuery传入的时间精度,需要yyyy-MM-dd HH:mm:ss,否则会报错在这里插入图片描述

  2. 这里对时间格式化分组,使用的是DateHistogramAggregationBuilder
    这个在EsApi7+就废弃了calendarInterval,替换新的fixedInterval

  3. 分组再聚合,注意嵌套关系,各位自己理解下subAggregation

  4. 最后数据查询出来后,迭代解析,注意理解ParsedDateHistogram取值、parsedDateHistogram.getBuckets()、迭代解析

总结

  • gs一直用老版本的ES6,这次终于被逼的更新了吧,真好。(之前一直建议、希望,都。。。。)
  • 本来很想引入EasyEs用用,但是总有同事不认可,算了
  • 之前也建议给ES装上sql-package插件,让DBeaver可以连接,试过一阵子,新版本又没装,算了
  • 其他就没啥好说的了,唯一就是restHighLevelClient现在在7+也被标记为过时了,下次有机会,这个再改改。
  • 希望能帮到大家,uping!

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

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

相关文章

根据实例逐行分析NIO到底在做什么

Selector&#xff08;选择器&#xff09;是 Channel 的多路复用器&#xff0c;它可以同时监控多个 Channel 的 IO 状况&#xff0c;允许单个线程来操作多个 Channel。Channel在从Buffer中获取数据。 选择器、通道、缓冲池是NIO的核心组件。 一、新建选择器 此时选择器内只包含…

设计模式之解释器模式的魅力:让代码读懂你的语言

目录 一、什么是解释器模式 二、解释器模式的应用场景 三、解释器模式的优缺点 3.1. 优点 3.2. 缺点 四、解释器模式示例 4.1. 问题描述 4.2. 问题分析 4.3. 代码实现 4.4. 优化方向 五、总结 一、什么是解释器模式 解释器模式&#xff08;Interpreter pattern&…

Spring: 在SpringBoot项目中解决前端跨域问题

这里写目录标题 一、什么是跨域问题二、浏览器的同源策略三、SpringBoot项目中解决跨域问题的5种方式&#xff1a;使用CORS1、自定 web filter 实现跨域(全局跨域)2、重写 WebMvcConfigurer(全局跨域)3、 CorsFilter(全局跨域)4、使用CrossOrigin注解 (局部跨域) 一、什么是跨域…

文件操作(顺序读写篇)

1. 顺序读写函数一览 函数名功能适用于fgetc字符输入函数所有输入流fputc字符输出函数所有输出流fgets文本行输入函数所有输入流fputs文本行输出函数所有输出流fscanf格式化输入函数所有输入流fprintf格式化输出函数所有输出流fread二进制输入文件fwrite二进制输出文件 上面说…

时序预测 | Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测

时序预测 | Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测 目录 时序预测 | Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现GWO-BP灰狼算法优化BP神经网络时间序列预测&#xff08;完整源码和数据…

如何在OceanBase的OCP多节点上获取日志

背景 在使用OceanBase的OCP的过程中&#xff0c;因各种因素&#xff0c;我们可能需要对当前页面进行跟踪。在单一ocp节点环境下&#xff0c;我们自然可以直接在该节点上查找所需的日志。然而&#xff0c;当我们的环境中部署了多个ocp节点时&#xff0c;在排查问题时就会变得相…

WPF中获取TreeView以及ListView获取其本身滚动条进行滚动

实现自行调节scoll滚动的位置(可相应获取任何控件中的内部滚动条) TreeView:TreeViewAutomationPeer lvap new TreeViewAutomationPeer(treeView); var svap lvap.GetPattern(PatternInterface.Scroll) as ScrollViewerAutomationPeer; var scroll svap.Owner as ScrollVie…

sql Tuning Advisor启用导致业务性能问题

数据库每天晚上10点后业务性能很卡&#xff0c;大量的insert被堵塞&#xff0c;查询等待事件发现有大量的“library cache lock”和“cursor: pin S wait on X”。 22:00数据库的统计信息开始收集&#xff0c; Sql Tuning Advisor堵塞了统计信息的收集&#xff0c;等待事件是“…

Python之Opencv教程(1):读取图片、图片灰度处理

1、Opencv简介 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个用于计算机视觉和图像处理的开源库&#xff0c;提供了丰富的图像处理、计算机视觉和机器学习功能。它支持多种编程语言&#xff0c;包括C、Python、Java等&#xff0c;广泛应用于图像处…

Redis 的慢日志

Redis 的慢日志 Redis 的慢日志&#xff08;Slow Log&#xff09;是用于记录执行时间超过预设阈值的命令请求的系统。慢日志可以帮助运维人员和开发人员识别潜在的性能瓶颈&#xff0c;定位那些可能导致 Redis 性能下降或响应延迟的慢查询。以下是 Redis 慢日志的相关细节&…

Linux IRC

目录 入侵框架检测 检测流程图 账号安全 查找账号中的危险信息 查看保存的历史命令 检测异常端口 入侵框架检测 1、系统安全检查&#xff08;进程、开放端口、连接、日志&#xff09; 这一块是目前个人该脚本所实现的功能 2、Rootkit 建议使用rootkit专杀工具来检查&#…

【算法-PID】

算法-PID ■ PID■ 闭环原理■ PID 控制流程■ PID 比例环节&#xff08;Proportion&#xff09;■ PID 积分环节&#xff08;Integral&#xff09;■ PID 微分环节&#xff08;Differential&#xff09; ■ 位置式PID&#xff0c;增量式PID介绍■ 位置式 PID 公式■ 增量式 PI…

嵌入式数据库-Sqlite3

阅读引言&#xff1a; 本文将会从环境sqlite3的安装、数据库的基础知识、sqlite3命令、以及sqlite的sql语句最后还有一个完整的代码实例&#xff0c; 相信仔细学习完这篇内容之后大家一定能有所收获。 目录 一、数据库的基础知识 1.数据库的基本概念 2.常用数据库 3.嵌入式…

wordpress插件,免费的wordpress插件

WordPress作为世界上最受欢迎的内容管理系统之一&#xff0c;拥有庞大的插件生态系统&#xff0c;为用户提供了丰富的功能扩展。在内容创作和SEO优化方面&#xff0c;有一类特殊的插件是自动生成原创文章并自动发布到WordPress站点的工具。这些插件能够帮助用户节省时间和精力&…

Hides for Mac:应用程序隐藏工具

Hides for Mac是一款功能强大的应用程序隐藏工具&#xff0c;专为Mac用户设计。它能够帮助用户快速隐藏当前正在运行的应用程序窗口&#xff0c;保护用户的隐私和工作内容&#xff0c;避免不必要的干扰。 软件下载&#xff1a;Hides for Mac下载 Hides for Mac的使用非常简单直…

初步了解C++

目录 一&#xff1a;什么是C&#xff1f; 二.C发展史 三:C关键字 四&#xff1a;命名空间 4.1命名空间的介绍 4.2命名空间的使用 4.3命名空间的使用 4.3.1使用作用域限定符 4.3.2 使用using将命名空间的某个成员引入 4.3.3使用using把整个命名空间展开 4.4命名空…

BaseDao封装增删改查

文章目录 什么是BaseDao操作代码增删改查询单个数据查询多个数据 总结 什么是BaseDao BaseDao是&#xff1a; 数据库里负责增加&#xff0c;删除&#xff0c;修改&#xff0c;查询 具体来说是一种接口代码,公共方法的接口类。 在dao层新建basedao,其他dao层接口继承basedao 相…

BC40056 Imports“SolidWorks.Interop.swconst”中指定的命名空间或类型不包含任何公共成员

BC40056 Imports“SolidWorks.Interop.swconst”中指定的命名空间或类型不包含任何公共成员&#xff0c;或者找不到该命名空间或类型。 问题描述原因分析 解决办法 ) 问题描述 严重性 代码 说明 项目 文件 行 警告 BC40056 Imports“SolidWorks.Interop.swconst”中指定的命名…

基于SSM框架的校园失物招领系统:从设计思路到实现细节

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

Java代码基础算法练习-自定义函数之字符串连接-2024.03.30

任务描述&#xff1a; 写一函数&#xff0c;将两个字符串连接起来&#xff0c;然后在主函数中调用该函数实现字符串连接操作。 任务要求&#xff1a; 代码示例&#xff1a; package M0317_0331;import java.util.Scanner;public class m240330 {public static void main(Stri…