Java 实现 Elasticsearch 查询当前索引全部数据

Java 实现 Elasticsearch 查询当前索引全部数据

  • 需求背景
  • 通常情况
  • Java 实现查询 Elasticsearch 全部数据
  • 写在最后

需求背景

通常情况下,Elasticsearch 为了提高查询效率,对于不指定分页查询条数的查询语句,默认会返回10条数据。那么这就会有一种情况,当你需要一次性返回 Elasticsearch 索引中的全部数据时,就无法实现了。这个时候你可能会考虑,比如我将每页取值的size 设置的很大,这样或许可以解决问题,但是数据量的上升你是无法控制的,最终会有一天数据量会超过你此时设置的最大 size,那么这就是一个雷点。并且如果一次查询很大量数据的话,即便是 Elasticsearch 查询效率高的索引结构可能也会导致查询时长较长,甚至响应超时。那么是否有一种查询效率高,且相对灵活的方式可以查询 Elasticsearch 的索引中全部数据呢?答案是:有的。

通常情况

下面来看一下在不设置 size 大小的情况下,执行 Elasticsearch 查询语句默认返回几条数据,结果是默认返回 10条。执行如下查询命令

GET crm_meiqia_conversation/_search

返回结果如图,这时我们看到返回了 10 条数据
在这里插入图片描述

此时如果你需要查询更多数据的话,你就可以通过指定 size 大小来查询更多数据,比如执行如下命令

GET crm_meiqia_conversation/_search
{"size":20
}

执行查询语句后返回的结果如图所示,索引查询会返回你指定 size 大小的数据
在这里插入图片描述

很明显,在一些特殊的场景下,想要一次性查询指定条件下的所有数据改如何操作呢,下面就来基于 Java 实现查询指定条件下的所有数据操作。

Java 实现查询 Elasticsearch 全部数据

在具体讲解如何通过 Java 实现查询 Elasticsearch 全部数据之前,我们可以先来看一下我已经实现之后的查询效果。这里你可以看到滚动州已经变得很小,这就是因为我查询出了指定条件下的全部数据导致的,而不是默认的 10 条数据
在这里插入图片描述

而如果没有实现查询指定索引指定条件下的全部数据时,看到的效果应该是这样的,默认只能一次性查询 10 条数据返回
在这里插入图片描述

下面再来讲一下如何通过 Java 实现 查询 es 全部数据,我们由浅入深来讲解,首先来看一下默认查询 es 10条数据的代码,Java 通过如下 SearchRequestBuilder searchRequest = client.prepareSearch(indexProperties.getMeiqiaConversationIndex()).setTypes(indexProperties.getMeiqiaConversationType()).setQuery(query); 构造查询 es 索引代码,这种情况没有设置 size 大小,默认的话就是查询指定索引下 10条数据,完整代码如下:

public AjaxResult getMeiqiaUidList(MeiqiaConversation meiqiaConversation) {BoolQueryBuilder query = QueryBuilders.boolQuery();BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();//会话idLong convId = meiqiaConversation.getConvId();if (convId != null) {boolQuery.filter(QueryBuilders.termQuery("convId",convId));}//会话日期String convStartDate = (String) meiqiaConversation.getParams().get("convStartDate");String convEndDate = (String) meiqiaConversation.getParams().get("convEndDate");if (StringUtils.isNotEmpty(convStartDate)) {Date date = DateUtils.stringToDate(convStartDate, DateUtils.SDF_YMDHMS);boolQuery.filter(QueryBuilders.rangeQuery("convStartDate").gte(date.getTime()));}if (StringUtil.isNotEmptyString(convEndDate)) {Date date = DateUtils.stringToDate(convEndDate, DateUtils.SDF_YMDHMS);boolQuery.filter(QueryBuilders.rangeQuery("convEndDate").lte(date.getTime()));}//会话日期Date convStartDate2 = meiqiaConversation.getConvStartDate();Date convEndDate2 = meiqiaConversation.getConvEndDate();if (Objects.nonNull(convStartDate2)) {boolQuery.filter(QueryBuilders.rangeQuery("convStartDate").gte(convStartDate2.getTime()));}if (Objects.nonNull(convEndDate2)) {boolQuery.filter(QueryBuilders.rangeQuery("convEndDate").lte(convEndDate2.getTime()));}//学号String uid = (String) meiqiaConversation.getParams().get("uid");if (StringUtils.isNotEmpty(uid)) {if (uid.contains("#")) {String replace = uid.replace("#", "");boolQuery.filter(QueryBuilders.termQuery("clientInfo.name",replace));}else {boolQuery.filter(QueryBuilders.termQuery("clientInfo.uid",uid));}}//客服工号String agentId = (String) meiqiaConversation.getParams().get("agentId");if (StringUtils.isNotEmpty(agentId)) {boolQuery.filter(QueryBuilders.termQuery("agentId",agentId));}// 会话内容String content = (String) meiqiaConversation.getParams().get("content");if (StringUtils.isNotEmpty(content)) {boolQuery.filter(QueryBuilders.matchPhrasePrefixQuery("convContent.content",content));}query.must(boolQuery);// 初始化搜索请求构建器,用于构造搜索请求SearchRequestBuilder searchRequest = client.prepareSearch(indexProperties.getMeiqiaConversationIndex())// 设置搜索的类型.setTypes(indexProperties.getMeiqiaConversationType())// 设置查询条件.setQuery(query);// 使用SearchRequest获取搜索响应SearchResponse searchResponse = searchRequest.get();// 初始化存储所有搜索结果的列表List<EsMeiqiaConversation> rows = new ArrayList<>();// 格式化搜索响应中的数据,并添加到rows列表中List<EsMeiqiaConversation> list1 = formatMeiqiaDto(searchResponse);rows.addAll(list1);//记录返回的uid nameList<MeiqiaConversation> list = new ArrayList<>();if (CollectionUtils.isNotEmpty(rows)) {//获取 uid nameMap<String, List<EsMeiqiaConversation>> collect = rows.stream().collect(Collectors.groupingBy(EsMeiqiaConversation::getClientUid, Collectors.toList()));Set<String> uids = collect.keySet();for (String u : uids) {MeiqiaConversation conv = new MeiqiaConversation();conv.setUid(u);//同一个uid 对应同一个 nameList<EsMeiqiaConversation> esconv = collect.get(u);String name = esconv.get(0).getClientName();conv.setName(name);list.add(conv);}}return AjaxResult.success(list);}

那么如何实现 一次查询满足条件的全部 es 数据呢,这就需要通过 scroll 实现,在初始化索引查询构造器时通过 SearchRequestBuilder searchRequest = client.prepareSearch(indexProperties.getMeiqiaConversationIndex()).setTypes(indexProperties.getMeiqiaConversationType()).setQuery(query).setSize(100).setScroll(TimeValue.timeValueMinutes(1)); 设置 scroll 参数来实现,同时需要再后续增加再次查询索引逻辑,将 scorllId 循环传递 获取全部数据,最终改造后的获取全部数据的代码如下

    public AjaxResult getMeiqiaUidList(MeiqiaConversation meiqiaConversation) {BoolQueryBuilder query = QueryBuilders.boolQuery();BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();//会话idLong convId = meiqiaConversation.getConvId();if (convId != null) {boolQuery.filter(QueryBuilders.termQuery("convId",convId));}//会话日期String convStartDate = (String) meiqiaConversation.getParams().get("convStartDate");String convEndDate = (String) meiqiaConversation.getParams().get("convEndDate");if (StringUtils.isNotEmpty(convStartDate)) {Date date = DateUtils.stringToDate(convStartDate, DateUtils.SDF_YMDHMS);boolQuery.filter(QueryBuilders.rangeQuery("convStartDate").gte(date.getTime()));}if (StringUtil.isNotEmptyString(convEndDate)) {Date date = DateUtils.stringToDate(convEndDate, DateUtils.SDF_YMDHMS);boolQuery.filter(QueryBuilders.rangeQuery("convEndDate").lte(date.getTime()));}//会话日期Date convStartDate2 = meiqiaConversation.getConvStartDate();Date convEndDate2 = meiqiaConversation.getConvEndDate();if (Objects.nonNull(convStartDate2)) {boolQuery.filter(QueryBuilders.rangeQuery("convStartDate").gte(convStartDate2.getTime()));}if (Objects.nonNull(convEndDate2)) {boolQuery.filter(QueryBuilders.rangeQuery("convEndDate").lte(convEndDate2.getTime()));}//学号String uid = (String) meiqiaConversation.getParams().get("uid");if (StringUtils.isNotEmpty(uid)) {if (uid.contains("#")) {String replace = uid.replace("#", "");boolQuery.filter(QueryBuilders.termQuery("clientInfo.name",replace));}else {boolQuery.filter(QueryBuilders.termQuery("clientInfo.uid",uid));}}//客服工号String agentId = (String) meiqiaConversation.getParams().get("agentId");if (StringUtils.isNotEmpty(agentId)) {boolQuery.filter(QueryBuilders.termQuery("agentId",agentId));}// 会话内容String content = (String) meiqiaConversation.getParams().get("content");if (StringUtils.isNotEmpty(content)) {boolQuery.filter(QueryBuilders.matchPhrasePrefixQuery("convContent.content",content));}query.must(boolQuery);// 初始化搜索请求构建器,用于构造搜索请求SearchRequestBuilder searchRequest = client.prepareSearch(indexProperties.getMeiqiaConversationIndex())// 设置搜索的类型.setTypes(indexProperties.getMeiqiaConversationType())// 设置查询条件.setQuery(query)// 设置返回结果的数量为100.setSize(100)// 设置滚动查询的时间间隔为1分钟.setScroll(TimeValue.timeValueMinutes(1));// 使用SearchRequest获取搜索响应SearchResponse searchResponse = searchRequest.get();// 初始化存储所有搜索结果的列表List<EsMeiqiaConversation> rows = new ArrayList<>();// 格式化搜索响应中的数据,并添加到rows列表中List<EsMeiqiaConversation> list1 = formatMeiqiaDto(searchResponse);rows.addAll(list1);// 使用Scroll方式遍历所有搜索结果do {// 准备下一次Scroll搜索,设置滚动时间为1分钟// 将scorllId循环传递 获取全部数据searchResponse = client.prepareSearchScroll(searchResponse.getScrollId()).setScroll(TimeValue.timeValueMinutes(1)).execute().actionGet();// 格式化新一批搜索结果,并添加到rows列表中List<EsMeiqiaConversation> list = formatMeiqiaDto(searchResponse);if (CollectionUtils.isNotEmpty(list)) {rows.addAll(list);}// 当搜索结果为空时,结束循环// 当searchHits的数组为空的时候结束循环,至此数据全部读取完毕} while (searchResponse.getHits().getHits().length != 0);// 创建一个ClearScrollRequest实例,用于清除滚动查询的会话。ClearScrollRequest clearScrollRequest = new ClearScrollRequest();// 将上一次查询返回的滚动ID添加到请求中,以便清除这个特定的会话。// 这是必要的,因为ClearScrollRequest需要至少一个滚动ID才能执行清除操作。clearScrollRequest.addScrollId(searchResponse.getScrollId());// 发送ClearScroll请求并获取操作的结果。// 这一步是必需的,因为它实际执行了清除滚动会话的操作,并允许我们处理结果或任何异常。client.clearScroll(clearScrollRequest).actionGet();//记录返回的uid nameList<MeiqiaConversation> list = new ArrayList<>();if (CollectionUtils.isNotEmpty(rows)) {//获取 uid nameMap<String, List<EsMeiqiaConversation>> collect = rows.stream().collect(Collectors.groupingBy(EsMeiqiaConversation::getClientUid, Collectors.toList()));Set<String> uids = collect.keySet();for (String u : uids) {MeiqiaConversation conv = new MeiqiaConversation();conv.setUid(u);//同一个uid 对应同一个 nameList<EsMeiqiaConversation> esconv = collect.get(u);String name = esconv.get(0).getClientName();conv.setName(name);list.add(conv);}}return AjaxResult.success(list);}

那么这段的核心代码是增加了滚动查询数据的操作,如图所示
在这里插入图片描述

同时再执行循环查询时将 scrollId 循环传递,并将查询结果 addAll 到当前list 的集合中
在这里插入图片描述

查询结束之后,最后是清除滚动会话的操作
在这里插入图片描述

到这里关于 Java 实现 es 查询指定条件下的全部数据操作就结束了,整个操作过程比较容易理解,增加了 es 滚动查询 scroll 操作来实现查询 es 全部数据。

写在最后

最后想要说的是,对于 es 查询,通常情况下是不需要一次性查询出当前索引所有条件下的数据的,毕竟数据量比较大,但是也有特殊的场景,这个时候不得不一次性查询出所有的数据,这就需要上文中用到的办法了,希望对大家有帮助。

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

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

相关文章

Elasticsearch ES|QL 地理空间索引加入纽约犯罪地图

可以根据地理空间数据连接两个索引。在本教程中&#xff0c;我将向你展示如何通过混合邻里多边形和 GPS 犯罪事件坐标来创建纽约市的犯罪地图。 安装 如果你还没有安装好自己的 Elasticsearch 及 Kibana 的话&#xff0c;请参考如下的链接来进行安装。 如何在 Linux&#xff0…

C#学习笔记 --- 简单应用

1.operator 运算符重载&#xff1a;使自定义类可以当做操作数一样进行使用。规则自己定。 2.partial 分部类&#xff1a; 同名方法写在不同位置&#xff0c;可以当成一个类使用。 3.索引器&#xff1a;使自定义类可以像数组一样通过索引值 访问到对应的数据。 4.params 数…

【Flink】Flink内存管理

Flink内存整体结构图&#xff1a; JobManager内存管理 JVM 进程总内存(Total Process Memory)Flink总内存(Total Flink Memory)&#xff1a;JVM进程总内存减去JVM Metaspace(元空间)和JVM Overhead(运行时开销)上图解释&#xff1a; JVM进程总内存为2G;JVM运行时开销(JVM Overh…

MYSQL8创建新用户报错:You have an error in your SQL syntax;check...

本文所用——MYSQL版本&#xff1a;8.0.25 baidu都是直接创建新用户并赋权&#xff0c;如下&#xff1a; GRANT ALL PRIVILEGES ON *.* TO 用户名% IDENTIFIED BY 密码 WITH GRANT OPTION;但是我用的MYSQL版本它就不行&#xff0c;会报错&#xff01; 经查阅资料发现——MY…

力扣经典练习题之198.打家劫舍

今天继续给大家分享一道力扣的做题心得今天这道题目是198.打家劫舍,这是一道非常经典的问题,在动态规划中经常考到这类问题,题目如下: 题目链接:198.打家劫舍 1,题目分析 首先此题就是给我们了一个数组,代表可以偷的房屋中的对应的金额,我们是一个小偷,一次可以偷很多…

万物互联的背后:MCU嵌入式硬件的奇幻之旅

文章背景&#xff1a;嵌入式硬件是什么&#xff1f; 你可能听说过嵌入式硬件&#xff0c;却总觉得它像是实验室里神秘的玩意儿。其实&#xff0c;它就在我们身边——从你手上的智能手表到车里的倒车雷达&#xff0c;无一不是嵌入式硬件的“杰作”。想象一块小小的电路板&#x…

【数据分析】一、初探 Numpy

目录 前言1. 一维 array 的生成2. 一维 array 的基本操作2.1. 查看属性2.2. 花式索引2.3. 条件筛查2.4. 数据统计 3. n 维 array 的生成4. n 维 array 的基本操作4.1. 查看属性4.2. 查询和切片4.3. 花式索引4.4. 矩阵 前言 Numpy是Python的常用开源数值计算扩展库&#xff0c;用…

2024年开发语言热度排名

随着技术的不断发展和变化&#xff0c;编程语言的热度也在不断演变。2024年即将到来&#xff0c;我们有必要回顾和展望当前和未来的开发语言市场。本文将基于多个因素&#xff0c;包括行业需求、社区支持、流行度以及新兴趋势&#xff0c;对2024年的开发语言热度进行排名和分析…

LabVIEW数据库管理系统

LabVIEW数据库管理系统&#xff08;DBMS&#xff09;是一种集成了数据库技术与数据采集、控制系统的解决方案。通过LabVIEW的强大图形化编程环境&#xff0c;结合数据库的高效数据存储与管理能力&#xff0c;开发人员可以实现高效的数据交互、存储、查询、更新和报告生成。LabV…

SQL语言的数据结构

SQL语言的数据结构及其应用 引言 SQL&#xff08;Structured Query Language&#xff09;是一种用于关系数据库管理系统&#xff08;RDBMS&#xff09;的标准语言&#xff0c;其核心功能是对存储在关系数据库中的数据进行查询、插入、更新和删除等操作。理解SQL语言中使用的数…

如何在 Linux、MacOS 以及 Windows 中打开控制面板

控制面板不仅仅是一系列图标和菜单的集合&#xff1b;它是通往优化个人计算体验的大门。通过它&#xff0c;用户可以轻松调整从外观到性能的各种参数&#xff0c;确保他们的电脑能够完美地适应自己的需求。无论是想要提升系统安全性、管理硬件设备&#xff0c;还是简单地改变桌…

Http 响应状态码 前后端联调

http 响应状态码 &#xff1a;是服务器在处理HTTP请求时返回的状态信息&#xff0c;用于表示请求的处理结果 1xx : 信息性状态码 100 Continue: 服务器已收到请求头部&#xff0c;客户端应继续发送请求体。 101 Switching Protocols : 切换协议。服务器已理解客户端的请求&a…

【文件锁】多进程线程安全访问文件demo

组合文件锁共享锁&#xff0c;并RAII 化&#xff0c;保证文件的跨进程线程读写安全。 demo模拟使用多个进程&#xff0c;每个进程包含多个线程对文件进行读写测试。 代码调用开源json库&#xff0c;需要下载到调试机器&#xff0c;编译时手动指定&#xff1a; g -stdc17 -pthr…

SVG图表

1、时序图 英文 #mermaid-svg-OyLuBTPnpbW9XDOB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-OyLuBTPnpbW9XDOB .error-icon{fill:#552222;}#mermaid-svg-OyLuBTPnpbW9XDOB .error-text{fill:#552222;stroke:#55…

python 轮廓 获取环形区域

目录 效果图&#xff1a; 代码&#xff1a; 效果图&#xff1a; 代码&#xff1a; import cv2 import numpy as np# 读取图像 image cv2.imread(rE:\project\jijia\tools_jijia\img_tools\ground_mask.jpg, cv2.IMREAD_GRAYSCALE) # 二值化图像 # 二值化图像 _, binary cv…

Clickhouse基础(一)

数据存储的目录&#xff0c;在存储数据时是先经过压缩后再存储的&#xff0c;压缩效率很高 操作命令&#xff1a; sudo clickhouse start sudo clickhouse restart sudo clickhouse status进入clickhouse clickhouse-client -mCREATE TABLE db_13.t_assist (modelId UInt64,…

基于spingbott+html+Thymeleaf的24小时智能服务器监控平台设计与实现

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…

从 SQL 语句到数据库操作

1. SQL 语句分类 数据定义语言 DDL &#xff1a; 用于定义或修改数据库中的结构&#xff0c;如&#xff1a;创建、修改、删除数据库对象。create、drop alter 数据操作语言 DML &#xff1a; 用于添加、删除、更新数据库中的数据。select、insert alter、drop 数据控制语言 D…

NLP三大特征抽取器:CNN、RNN与Transformer全面解析

引言 自然语言处理&#xff08;NLP&#xff09;领域的快速发展离不开深度学习技术的推动。随着应用需求的不断增加&#xff0c;如何高效地从文本中抽取特征成为NLP研究中的核心问题。深度学习中三大主要特征抽取器——卷积神经网络&#xff08;Convolutional Neural Network, …

Excel中SUM求和为0?难道是Excel有Bug!

大家好&#xff0c;我是小鱼。 在日常工作中有时会遇到这样的情况&#xff0c;对Excel表格数据进行求和时&#xff0c;结果竟然是0&#xff0c;很多小伙伴甚至都怀疑是不是Excel有Bug&#xff01;其实&#xff0c;在WPS的Excel表格中数据求和&#xff0c;结果为0无法正确求和的…