Using scrolls in Java

一般搜索请求都是返回一”页”数据,无论数据量多大都一起返回给用户,Scroll API可以允许我们检索大量数据(甚至全部数据)。Scroll API允许我们做一个初始阶段搜索并且持续批量从Elasticsearch里拉取结果直到没有结果剩下。这有点像传统数据库里的cursors(游标)。

Scroll API的创建并不是为了实时的用户响应,而是为了处理大量的数据(Scrolling is not intended for real time user requests, but rather for processing large amounts of data)。从 scroll 请求返回的结果只是反映了 search 发生那一时刻的索引状态,就像一个快照(The results that are returned from a scroll request reflect the state of the index at the time that the initial search request was made, like a snapshot in time)。后续的对文档的改动(索引、更新或者删除)都只会影响后面的搜索请求。

import static org.elasticsearch.index.query.QueryBuilders.*;

QueryBuilder qb = termQuery("multi", "test");

SearchResponse scrollResp = client.prepareSearch(test)

.addSort(FieldSortBuilder.DOC_FIELD_NAME, SortOrder.ASC)

.setScroll(new TimeValue(60000)) //为了使用 scroll,初始搜索请求应该在查询中指定 scroll 参数,告诉 Elasticsearch 需要保持搜索的上下文环境多长时间(滚动时间)

.setQuery(qb)

.setSize(100).get(); //max of 100 hits will be returned for each scroll

//Scroll until no hits are returned

do {

for (SearchHit hit : scrollResp.getHits().getHits()) {

//Handle the hit...

}

scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();

} while(scrollResp.getHits().getHits().length != 0); // Zero hits mark the end of the scroll and the while loop.

如果超过滚动时间,继续使用该滚动ID搜索数据,则会报错:

Caused by: SearchContextMissingException[No search context found for id [2861]]

at org.elasticsearch.search.SearchService.findContext(SearchService.java:613)

at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:403)

at org.elasticsearch.search.action.SearchServiceTransportAction$SearchQueryScrollTransportHandler.messageReceived(SearchServiceTransportAction.java:384)

at org.elasticsearch.search.action.SearchServiceTransportAction$SearchQueryScrollTransportHandler.messageReceived(SearchServiceTransportAction.java:381)

at org.elasticsearch.transport.TransportRequestHandler.messageReceived(TransportRequestHandler.java:33)

at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:75)

at org.elasticsearch.transport.TransportService$4.doRun(TransportService.java:376)

at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at java.lang.Thread.run(Thread.java:745)

虽然当滚动有效时间已过,搜索上下文(Search Context)会自动被清除,但是一值保持滚动代价也是很大的,所以当我们不在使用滚动时要尽快使用Clear-Scroll API进行清除。

清除Scroll

/**

* 清除滚动ID

* @param client

* @param scrollIdList

* @return

*/

public static boolean clearScroll(Client client, List scrollIdList){

ClearScrollRequestBuilder clearScrollRequestBuilder = client.prepareClearScroll();

clearScrollRequestBuilder.setScrollIds(scrollIdList);

ClearScrollResponse response = clearScrollRequestBuilder.get();

return response.isSucceeded();

}

/**

* 清除滚动ID

* @param client

* @param scrollId

* @return

*/

public static boolean clearScroll(Client client, String scrollId){

ClearScrollRequestBuilder clearScrollRequestBuilder = client.prepareClearScroll();

clearScrollRequestBuilder.addScrollId(scrollId);

ClearScrollResponse response = clearScrollRequestBuilder.get();

return response.isSucceeded();

}

实例

public class ScrollsAPI extends ElasticsearchClientBase {

private String scrollId;

@Test

public void testScrolls() throws Exception {

SearchResponse scrollResp = client.prepareSearch("twitter")

.addSort(FieldSortBuilder.DOC_FIELD_NAME, SortOrder.ASC)

.setScroll(new TimeValue(60000)) //为了使用 scroll,初始搜索请求应该在查询中指定 scroll 参数,告诉 Elasticsearch 需要保持搜索的上下文环境多长时间(滚动时间)

.setQuery(QueryBuilders.termQuery("user", "kimchy")) // Query 查询条件

.setSize(5).get(); //max of 100 hits will be returned for each scroll

//Scroll until no hits are returned

scrollId = scrollResp.getScrollId();

do {

for (SearchHit hit : scrollResp.getHits().getHits()) {

//Handle the hit...

System.out.println("" + hit.getSource().toString());

}

scrollResp = client.prepareSearchScroll(scrollId).setScroll(new TimeValue(60000)).execute().actionGet();

}

while (scrollResp.getHits().getHits().length != 0); // Zero hits mark the end of the scroll and the while loop.

}

@Override

public void tearDown() throws Exception {

ClearScrollRequestBuilder clearScrollRequestBuilder = client.prepareClearScroll();

clearScrollRequestBuilder.addScrollId(scrollId);

ClearScrollResponse response = clearScrollRequestBuilder.get();

if (response.isSucceeded()) {

System.out.println("成功清除");

}

super.tearDown();

}

}

in the java search_Search API – Using scrolls in Java - Elasticsearch Java API 手册相关推荐

  1. Elasticsearch Java API 6.2(java client)

    前言 本节描述了Elasticsearch提供的Java API,所有的Elasticsearch操作都使用客户端对象执行,所有操作本质上都是完全异步的(要么接收监听器,要么未来返回). 此外,客户端 ...

  2. Java中的微信支付(2):API V3 微信平台证书的获取与刷新

    1. 前言 在Java 中的微信支付(1):API V3 版本签名详解一文中胖哥讲解了微信支付 V3 版本 API 的签名,当我方(你自己的服务器)请求微信支付服务器时需要根据我方的API 证书对参数 ...

  3. java遍历栈_Java中使用StackWalker和Stream API进行堆栈遍历

    1.Java 9以前堆栈遍历到目前为止,官方解决方案是获取当前线程并调用其getStackTrace()方法: StackTraceElement[] stackTraceElements = Thr ...

  4. Java中的一些零星容易被忽略的API(及时补充)

    关于Java中的Arrays.copyOfRange()方法 要使用这个方法,首先要import java.util.*; Arrays.copyOfRange(T[]original,int fro ...

  5. Elasticsearch java api(五) Bulk批量索引

    一.Bulk API 使用bulk命令时,REST API以_bulk结尾,批量操作写在json文件中,官网给出的语法格式: action_and_meta_data\n optional_sourc ...

  6. ElasticSearch Java Api(四) -删除索引

    删除可以是删除整个索引库,也可以根据文档id删除索引库下的文档,还可以通过query查询条件删除所有符合条件的数据. 一.删除整个索引库 下面的例子会删除indexName索引: DeleteInde ...

  7. ElasticSearch Java Api(一) -创建索引

    ElasticSearch Java API官网文档:https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/jav ...

  8. java 反射api_反射是最重要的Java API

    java 反射api 前几天我在想-这是最重要的Java API. 哪种SE和EE API可以使大多数Java生态系统成为可能,而哪些API不能重新创建为第三方库. 正如您可能已经猜到标题一样,我认为 ...

  9. java redis 命令_命令界面:使用Java中的动态API处理Redis

    java redis 命令 Redis是一个数据存储,支持190多个文档化命令和450多个命令排列. 社区积极支持Redis开发: 每个主要的Redis版本都附带新命令. 今年,Redis向第三方供应 ...

  10. Java SE 11(18.9)中的API更新

    Java SE 11也被命名为18.9(基于使用发布年份和月份的新命名方案),预计将在9月的最后一周发布GA. 频繁发布新JDK版本的新方法是允许语言创建者引入新功能,并向开发人员社区更快地进行API ...

最新文章

  1. 8个必备的PHP功能开发
  2. [HEOI2017] 相逢是问候
  3. CentOS LAMP一键安装网站环境及添加域名
  4. UVa 10420 List of Conquests
  5. 如何选择适合自己公司的移动办公系统?
  6. VTK:模型之ExtractLargestIsosurface
  7. android 获取配置文件 相对路径
  8. golang-gui编程
  9. linux vim 添加注释_vim基础教程
  10. python基础-PyCharm设置作者信息模板_修改解释器_设置软件UTF-8编码
  11. django/python日志logging 的配置以及处理
  12. 对抗网络学习-FGSM对抗样本生成
  13. HTML+CSS大作业——水果介绍-橙子之家(6页) HTML+CSS+JavaScript 学生dreamweaver网页设计作业成品
  14. 走进音视频的世界——剖析exo播放器架构
  15. 基于51单片机的液位监测系统仿真数码管显示程序原理图
  16. t检验、方差分析、卡方检验统计量的构造
  17. GEA 3.4 流水线、缓存及优化
  18. 20_django项目的部署和总结
  19. 网易163企业邮箱注册申请,有什么优惠活动
  20. gocolly-登录(5)

热门文章

  1. F-LOAM:基于激光雷达的快速里程计和建图
  2. 舒工给您娓娓道来:2019-nCoV,教室布局筛查追溯系统算法解密!
  3. 如何从ATS获取客户端平均响应时间(单位,毫秒)?
  4. ATS缓存中间层介绍
  5. params.success params.success(res.data)
  6. rsa证书ssh登陆服务器
  7. 利用jdt快速实现pmd的功能
  8. Linux日常命令记录
  9. 关于使用strtok的一个小问题
  10. SQL Server 中update的小计