java使用ElasticSearch的scroll查询,高效的解决es查询数量的限制。
java使用ElasticSearch的scroll查询,高效的解决es查询数量的限制。
一、为什么要使用ES的scroll
(1)首先我们要明白es的查询机制:ES的搜索是分2个阶段进行的,即Query阶段和Fetch阶段。
Query阶段比较轻量级,通过查询倒排索引,获取满足查询结果的文档ID列表。
Fetch阶段比较重,需要将每个分片的查询结果取回,在协调结点进行全局排序。 通过From+size这种方式分批获取数据的时候,随着from加大,需要全局排序并丢弃的结果数量随之上升,性能越来越差。
(2)es在进行普通的查询时,默认只给查询出来十条数据。
通过设置size的值可以使查询结果从10增大到1000条数据,当超出1000条数据的时候就会只显示出来1000条数据。
为了解决上面的问题可以采用一种效率比较低的方法,在创建索引的时候添加如下配置
"settings":{"index":{"max_result_window": 在这里填入你需要的大小 }}
(3)如果进行高效的查询呢?那就需要使scroll滚动查询了。
Scroll查询,先做轻量级的Query阶段以后,免去了繁重的全局排序过程。 它只是将查询结果集,也就是doc_id列表保留在一个上下文里, 之后每次分批取回的时候,只需根据设置的size,在每个分片内部按照一定顺序(默认doc_id续), 取回size数量大小的数据即可。
二、如何使用scroll
(1)首先引入elasticsearch的坐标
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>
(2)编写如下代码
/*** 使用es的scroll方法来滚动查询es的数据,可以有效的解决大数据容量读取的限制* @param index es的索引名称* @param host es的主机ip号* @param port es的端口号* @param beginDate 构造查询条件需要的条件之一 (可以根据自己需求定义es的查询条件)* @param endDate 构造查询条件需要的条件之一 (可以根据自己需求定义es的查询条件)*/public void scrollDemo(String index,String host,int port,String beginDate,String endDate) throws ParseException {RestHighLevelClient restHighLevelClient=new RestHighLevelClient(RestClient.builder(new HttpHost(host,port,"http")));//构造查询条件SearchRequest searchRequest = new SearchRequest(index);SearchSourceBuilder builder = new SearchSourceBuilder();//设置查询超时时间Scroll scroll = new Scroll(TimeValue.timeValueMinutes(5L));builder.query(QueryBuilders.rangeQuery("datetime").gte(beginDate).lte(endDate));//设置最多一次能够取出1000笔数据,从第1001笔数据开始,将开启滚动查询 //PS:滚动查询也属于这一次查询,只不过因为一次查不完,分多次查builder.size(1000);searchRequest.source(builder);//将滚动放入searchRequest.scroll(scroll);SearchResponse searchResponse = null;try {searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);} catch (IOException e) {System.out.println("查询索引库失败");}SearchHits hits= searchResponse.getHits();SearchHit[] hit= hits.getHits();/***在这个位置已经读到了前一千条数据,可以在这先对这一千数据进行处理。下面滚动查询剩下的数据*///记录要滚动的IDString scrollId = searchResponse.getScrollId();//滚动查询部分,将从第1001笔数据开始取SearchHit[] hitsScroll = hits.getHits();while (hitsScroll != null && hitsScroll.length > 0 ) {//构造滚动查询条件SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);searchScrollRequest.scroll(scroll);try {//响应必须是上面的响应对象,需要对上一层进行覆盖searchResponse = restHighLevelClient.scroll(searchScrollRequest, RequestOptions.DEFAULT);} catch (IOException e) {System.out.println("滚动查询失败");}scrollId = searchResponse.getScrollId();hits = searchResponse.getHits();hitsScroll = hits.getHits();/***在这个位置可以对滚动查询到的从1001条数据开始的数据进行处理。*/}//清除滚动,否则影响下次查询ClearScrollRequest clearScrollRequest = new ClearScrollRequest();clearScrollRequest.addScrollId(scrollId);ClearScrollResponse clearScrollResponse = null;try {clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest,RequestOptions.DEFAULT);} catch (IOException e) {System.out.println("滚动查询删除失败");}//清除滚动是否成功boolean succeeded = clearScrollResponse.isSucceeded();}
java使用ElasticSearch的scroll查询,高效的解决es查询数量的限制。相关推荐
- Elasticsearch在docker下安装运行,ES查询、分词器
目录 Elasticsearch的一点背景 数据输入 数据输出 集群 集群灾备 集群管理 Docker容器中运行ElasticSearch.Kibana.cerebro ElasticSearch K ...
- Elasticsearch(ES6)------(5)kibana的es查询、mysql查询转换和对应javaAPI使用(一)
准备数据测试数据 我这里提前在mysql中造好了一些数据,通过javaAPI导入到es中 mysql建表语句 CREATE TABLE `product_item` (`product_id` int ...
- php redis 分页查询,redis如何解决分页查询
我们都知道,通过缓存查询的结果,可以极大的提升系统的服务能力,以及降低底层服务或者是数据库的压力.对于有分页条件的缓存,我们也可以按照不同的分页条件来缓存多个key. 基于SortedSet的分页查询 ...
- java 查询 代码_java使用es查询的示例代码
众所周知,elasticsearch简称es,它是基于基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开 ...
- oracle锁表查询_专业解决 MySQL 查询速度慢与性能差
Java识堂,一个高原创,高收藏,有干货的微信公众号,一起成长,一起进步,欢迎关注 什么影响了数据库查询速度 1.1 影响数据库查询速度的四个因素 1.2 风险分析 QPS: QueriesPerSe ...
- 加锁查询 FOR UPDATE 解决表格查询极慢的问题
Select...for update 语句是我们经常使用手工加锁语句.通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作.同时,在多版本一致读机制的支持下,select语 ...
- 解决es查询异常:lasticsearch exception [type=illegal_argument_exception, reason=Can‘t load fielddata on....
Elasticsearch exception [type=illegal_argument_exception, reason=Can't load fielddata on [brandName] ...
- es查询-统计总数以及深度分页
一.查询总数 1. ES 查询 hits 统计总数不准? 当我们使用 ES 的时候,有时会比较关心匹配到的文档总数是多少,所以在查询得到结果后会使用 hits.total.value 这个值作为匹配 ...
- java操作elasticsearch实现前缀查询、wildcard、fuzzy模糊查询、ids查询
1.前缀查询(prefix) //prefix前缀查询 @Testpublic void test15() throws UnknownHostException {//1.指定es集群 cluste ...
最新文章
- 手把手教你如何扩展GridView之自带CheckBox
- nginx收到空包问题
- python 为html页面增加背景_Python 给html css自动添加注释
- 201126阶段二单例数据库及MVC设计模式
- HTML精仿ios相册,iOS开发-仿微信相册选择Demo
- jsf刷新页面_JSF页面生命周期管理
- C#反射的Assembly的简单应用
- 上传本地代码到GitHub遇到问题记录
- Android开发之数据库Sqlite
- 香农编码,哈夫曼编码与费诺编码的比较
- 阿里云服务器配置好了,为什么访问不了?阿里云安全组放行1433端口设置您知道吗?
- 自定义容器实现类似Windows屏保功能
- 使用Java实现一个简单的贪吃蛇小游戏
- 通过CrossTalk在Delphi中使用ADO.Net(1)
- 拆解B站内容运营新思路,UP主如何在内卷严重赛道中“求同存异”
- 重新认识java(十一)---- java中的数组
- 《电脑编程技巧与维护2008年合订本》
- 【闲趣】JavaScript练手项目:艳火
- 定了!全省公办高校辅导员全部入编!
- TikTok运营玩法攻略总结,从输出内容再到变现