集成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.mzph.cn/news/773103.shtml

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

相关文章

docker快速安装Es和kibana

文章目录 概要一、Es二、kibana三、dcoker compose管理四、参考 概要 在工作过程中&#xff0c;经常需要测试环境搭建Es环境&#xff0c;本文基于Es V8.12.2来演示如何快速搭建单节点Es和kibana。 服务器默认已按装docker 一、Es 1&#xff1a;拉取镜像 docker pull elast…

课时76:流程控制_while循环_嵌套案例

1.2.3 嵌套案例 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 简介 这里的嵌套实践&#xff0c;与选择语句的嵌套实践基本一致&#xff0c;只不过组合的方式发生了一些变化。常见的组合样式如下&#xff1a;while嵌套while语句…

docker安装elasticseachkibana

1.docker安装es 创建本机挂载目录&#xff0c;与容器上目录映射 /Users/wangpei/2024/mydata/elasticsearch conf下创建yml文件 echo "http.host : 0.0.0.0" >> /Users/wangpei/2024/mydata/elasticsearch/config/elasticsearch.yml 安装容器&#xff1a; d…

Ansys Speos | Light Expert Group探测器组使用技巧

附件下载 联系工作人员获取附件 概述 相机挡板的设计需要在光路的不同位置同步多个照度图&#xff0c;以尽量减少杂散光。2023R2 Speos提供了一种新的探测器&#xff0c;用于高阶杂散光分析&#xff0c;可以同时对多个探测器进行光线追迹。Light Expert工具可以即时过滤3D视…

Day48:WEB攻防-PHP应用文件上传中间件CVE解析第三方编辑器已知CMS漏洞

目录 PHP/ASP-中间件-上传相关-IIS&Apache&Nginx(解析漏洞) IIS Apache Nginx PHP-编辑器-上传相关-第三方处理引用 PHP-CMS源码-上传相关-已知识别到利用 知识点&#xff1a; 1、PHP-中间件-文件上传-CVE&配置解析 2、PHP-编辑器-文件上传-第三方引用安全 3…

C#学习笔记3:Windows窗口计时器

今日继续我的C#学习之路&#xff0c;今日学习自己制作一个Windows窗口计时器程序&#xff1a; 文章提供源码解释、步骤操作、整体项目工程下载 完成后的效果大致如下&#xff1a;&#xff08;可选择秒数&#xff0c;有进度条&#xff0c;开始计时按钮等&#xff09; &#xf…

C++的string类(二):string类的实际OJ应用

目录 1、找出字符串中第一个只出现一次的字符 2、字符串相乘 3、反转字符串中的单词 III 4、反转字符串 II 5、字符串相加 6、验证回文串 7、字符串最后一个单词的长度 8、字符串中的第一个唯一字符 9、仅仅反转字母 1、找出字符串中第一个只出现一次的字符 #include…

Day32:学习SpringCloud

学习计划&#xff1a;完成尚硅谷的尚上优选项目 学习进度&#xff1a;完成尚上优选项目的前置知识点&#xff1a;SpringCloud 知识点&#xff1a; 面试相关问题及源码 Redis篇 Redis与Memcache的区别&#xff1f;Redis的单线程问题Redis的持久化方案由哪些&#xff1f;Redis…

nacos服务分级存储(权重配置)

需求&#xff1a;服务器分级存储的访问优先级&#xff1f; 一个服务可以有多个实例&#xff0c;例如我们的user-service&#xff0c;可以有: 127.0.0.1:8081 127.0.0.1:8082 127.0.0.1:8083 这里user服务copy了三个实例出来、。 127.0.0.1:8083杭州127.0.0.1:8082成都127.…

Python包管理工具 pip 及其常用命令和参数用法

目录 PIP 主要功能 安装包 升级包 卸载包 列出包 检查依赖 pip的配置和环境 主要用法 1&#xff1a;版本 2&#xff1a;安装 Python 库 3&#xff1a;升级库 4&#xff1a;卸载库 5&#xff1a;搜索库 6&#xff1a;查看已安装库详细信息 7&#xff1a;只下载库…

POE供电IP网络广播号角 网络号角喇叭SV-7044

POE供电IP网络广播号角 网络号角喇叭SV-7044 SV-7044是一款网络号角喇叭&#xff0c;具有10/100M以太网接口&#xff0c;从网络接口接收网络的音频数据后播放。 本网络号角喇叭内置有一个高品质扬声器&#xff0c;提供立体声的音频播放。该网络号角喇叭可以直接播放来自网络的音…

00000基础搭建vue+flask前后端分离项目

我完全是参考的这个vue3flask前后端分离环境速建_flask vue3-CSDN博客 安装了node_js&#xff08;添加了环境变量&#xff09; 环境变量 把原来的镜像源换成了淘宝镜像源 npm config set registry https://registry.npmmirror.com/ 查看版本证明安装成功 npm - v 安装npm i…

学习Dive into Deep learning:2.1数据操作,张量(tensor)

首先&#xff0c;我们介绍n维数组&#xff0c;也称为张量&#xff08;tensor&#xff09;。 使用过Python中NumPy计算包的读者会对本部分很熟悉。 无论使用哪个深度学习框架&#xff0c;它的张量类&#xff08;在MXNet中为ndarray&#xff0c; 在PyTorch和TensorFlow中为Tensor…

(二)Eureka服务搭建,服务注册,服务发现

1.Eureka注册中心 假如我们的服务提供者user-service部署了多个实例&#xff0c;如图&#xff1a; 存在几个问题&#xff1a; order-service在发起远程调用的时候&#xff0c;该如何得知user-service实例的ip地址和端口&#xff1f;有多个user-service实例地址&#xff0c;…

HCIP—BGP路由发布

R1和R2&#xff0c;R4和R5建立EBGP对等体 R1和R2&#xff08;R4和R5&#xff09;之间属于EBGP对等体&#xff0c;可以使用直连物理接口建立对等体关系&#xff0c;TTL值默认1。由于使用直连物理接口方式建立&#xff0c;刚好一跳到达。 [R1]bgp 100 [R1-bgp]router-i…

gateway做负载均衡

在Spring Cloud中&#xff0c;Gateway可以通过配置文件来实现负载均衡。以下是一个简单的配置示例&#xff0c;它演示了如何将请求代理到名为service-instance的服务的两个不同实例。 spring:cloud:gateway:routes:- id: service-instance-routeuri: lb://service-instancepre…

【Frida】【Android】02_JAVA层HOOK

&#x1f6eb; 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…

【Vue】创建vue项目 npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED

在安装完vue后&#xff0c;一段时间后发现再次使用出错&#xff1b;感觉可能是使用了代理的原因&#xff0c;但是就算关闭了代理一样不行&#xff1b;最后重启大法解决。 此处记录解决时使用到的命令。 检查版本 node -v cnpm -v vue --version vue -V安装 npm install -g vu…

Trapcode Particular---打造惊艳粒子效果

Trapcode Particular是Adobe After Effects中的一款强大3D粒子系统插件&#xff0c;其能够创造出丰富多样的自然特效&#xff0c;如烟雾、火焰和闪光&#xff0c;以及有机的和高科技风格的图形效果。Trapcode Particular功能丰富且特色鲜明&#xff0c;是一款为Adobe After Eff…

用 JavaScript 发起 HTTP 请求的几种方法

JavaScript 具有非常棒的模块和方法&#xff0c;可以用来建立可从服务器端资源发送或接收数据的 HTTP 请求。本文会带着大家一起看看在 JavaScript 中常用的建立 HTTP 请求的方式有哪些。 Ajax Ajax 是最常规的建立异步 HTTP 请求的方式。你可以使用 HTTP POST 方法来发送数据…