Elasticsearch - 滚动查询scroll

  • 简介
  • 实践中我使用到滚动的场景
  • from-size分页的缺点
  • json处理步骤
    • 案例如下
  • java 处理步骤
    • 代码逻辑
    • 简化版java代码如下:

简介

   Elasticsearch滚动查询也叫游标查询

   适合那种需要一次性或分批拉出大量数据做离线处理、迁移等。可以提升点效率。

实践中我使用到滚动的场景

  • 需求需要从几个不同的es数据源拉取、截取数据,合到一个新的业务数据源中。
  • 每天夜里有定时任务需要拉取某天的索引数据,根据某个字段去重后拿去做离线业务处理。

注意:scroll不适合支持那种实时的和用户交互的前端分页工作,实时分页查询可以使用from-size方式。但同时from-size也不适用上述离线大数据量处理业务场景。

from-size分页的缺点

GET /{index_name}/_search
{"from":0,
"size":10
}

   es客户端实时分页一般使用from-size。如果有100条数据,按size=10共分10页,那么当用户查询第n页的时候,实际上es是把前n页的数据全部找出来,再去除前n-1页最后得到需要的数据返回,查最后一页就相当于全扫描。其中利弊大家自行思考。所以离线大批量数据的处理业务或迁移不适合使用from-size方式查询。

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.from((page.getPageNum() - 1) * page.getPageSize());
searchSourceBuilder.size(page.getPageSize());

json处理步骤

   我们可以给初始化查询传递参数scroll=5m ,es会返回一个_scroll_id,这是一个base64编码的长字符串,用于下次查询时传入。5m表示_scroll_id缓存5分钟,之后自动过期,可以根据需要配置。size可以指定每次滚动拉取多少数据。不过如果你做了分片,查询结果可能超过指定的 size 大小。

案例如下

例如:第一次查询

GET /sms/_search?scroll=5m
{"size": 20,"query": {"bool": {"must": [{"match": {"userId": "9d995c0b90fe4128896a1a84eca213bf"}}]}}
}

返回:

{"_scroll_id": "DnF1ZXJ5VGhlbkZldGNoBgAAAAAATJH1FlFTYzlSZ0VNVGdlM2o0T0dTX2tVUncAAAAAAE0-zBZQUVp6Sy04X1J1NjJCaVZfQUhHWjFnAAAAAABMkfYWUVNjOVJnRU1UZ2UzajRPR1Nfa1VSdwAAAAAATXVxFk83UWRhNGg3UmxTQnpXTEUzd0dreXcAAAAAAEyR9xZRU2M5UmdFTVRnZTNqNE9HU19rVVJ3AAAAAABNPs0WUFFaekstOF9SdTYyQmlWX0FIR1oxZw==","took": 6,......
}

之后我们把上一次得到的_scroll_id拿到按以下查询即可得到下一轮的数据。

GET /_search/scroll/
{"scroll":"1m","scroll_id":"DnF1ZXJ5VGhlbkZldGNoBgAAAAAATJH1FlFTYzlSZ0VNVGdlM2o0T0dTX2tVUncAAAAAAE0-zBZQUVp6Sy04X1J1NjJCaVZfQUhHWjFnAAAAAABMkfYWUVNjOVJnRU1UZ2UzajRPR1Nfa1VSdwAAAAAATXVxFk83UWRhNGg3UmxTQnpXTEUzd0dreXcAAAAAAEyR9xZRU2M5UmdFTVRnZTNqNE9HU19rVVJ3AAAAAABNPs0WUFFaekstOF9SdTYyQmlWX0FIR1oxZw=="
}

除了等待scroll_id过期时间之外,我们也可以手动删除scroll_id:


// 手动删除scroll_id的方法
DELETE /_search/scroll { "scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBgAAAAAATJH1FlFTYzlSZ0VNVGdlM2o0T0dTX2tVUncAAAAAAE0-zBZQUVp6Sy04X1J1NjJCaVZfQUhHWjFnAAAAAABMkfYWUVNjOVJnRU1UZ2UzajRPR1Nfa1VSdwAAAAAATXVxFk83UWRhNGg3UmxTQnpXTEUzd0dreXcAAAAAAEyR9xZRU2M5UmdFTVRnZTNqNE9HU19rVVJ3AAAAAABNPs0WUFFaekstOF9SdTYyQmlWX0FIR1oxZw==" }

java 处理步骤

代码逻辑
  • 我们可以使用一个循环去查询,第一次查询的时候按需要的查询条件处理,加上参数scroll即可,
  • 之后的查询均使用GET /_search/scroll/ 传递_scroll_id查询,如果返回数据为空则终止循环。

es version: 6.3.2

 <dependency><groupId>io.searchbox</groupId><artifactId>jest</artifactId></dependency>
简化版java代码如下:
String rollId = null;
//滚动查询
while (true) {// 第一次查询if (rollId == null) {// 按业务需求查询JestResult jestResult = jestSmsClient.execute(getSmsShortSearchBuilder(createDate));if (jestResult.isSucceeded()) {// 获取scroll_id以备下次查询rollId =  jestResult.getJsonObject().get("_scroll_id").getAsString();//获取查询结果业务处理result = .......}} else {// 后续查询使用rollIdJestResult jestResult = jestSmsClient.execute(new SearchScroll.Builder(rollId, "5m").build());if (jestResult.isSucceeded()) {// 获取scroll_id以备下次查询rollId =  jestResult.getJsonObject().get("_scroll_id").getAsString();//获取查询结果业务处理result =  .......}}// 没有数据返回,你也可以认为:如果返回的数据长度小于size时可以跳出循环。没毛病可能会少调用一次es。不过可能会由于多个分片导致并没有少调用一次if(CollectionUtils.isEmpty(result)) {break;}
}

稍微写详细点凑下字数:

public final static String ES_INDEX = "es索引名";
public final static String ES_TYPE = "_doc";
String rollId = null;
//滚动查询
while (true) {List<Xxxx> result = Lists.newArrayList();//首次访问if (rollId == null) {try {SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();searchSourceBuilder.query(boolQueryBuilder);searchSourceBuilder.size(10000);searchSourceBuilder.fetchSource(new String[]{"sendUrl"}, new String[]{});Search search = new Search.Builder(searchSourceBuilder.toString()).addIndex(Constants.ES_INDEX).addType(Constants.ES_TYPE).setParameter("preference", "_primary_first").setParameter(Parameters.SCROLL, "5m").build();JestResult jestResult = jestSmsClient.execute(search);if (jestResult.isSucceeded()) {rollId =  jestResult.getJsonObject().get("_scroll_id").getAsString();result = jestResult.getSourceAsObjectList(Xxxx.class, false);}} catch (IOException e) {log.error("异常信息:", e);return null;}} else {try {JestResult jestResult = jestSmsClient.execute(new SearchScroll.Builder(rollId, "5m").build());if (jestResult.isSucceeded()) {rollId =  jestResult.getJsonObject().get("_scroll_id").getAsString();result = jestResult.getSourceAsObjectList(Xxxx.class, false);}} catch (IOException e) {log.error("异常信息:", e);return null;}}if(CollectionUtils.isEmpty(result)) {break;}//对返回数据做处理result ...省略
}

ok,结束了。莫莫绵溜了溜了。。


水平有限,如果你觉得上述有任何疑问、不足、错误的地方,欢迎在评论区指正。


ES - 滚动查询(scroll)相关推荐

  1. 【ES实战】Search的滚动查询(Scroll)

    滚动查询(Scroll) 虽然搜索请求返回结果是单个"页面",但scroll API 可用于从单个搜索请求中检索大量结果(甚至所有结果),其方式与在传统数据库使用相似. scrol ...

  2. SpringBoot整合ES高级查询

    SpringBoot整合ES高级查询 springboot版本:2.0.5.RELEASE elasticsearch版本:7.9.1 1.配置 引入依赖: <dependency>< ...

  3. ES分页查询时报错“Result window is too large ...”

    ES分页查询时报错"Result window is too large ..." 问题出现缘由 报错详情 错误译文 解决办法 问题出现缘由 ES 中存储了索引数据,使用 ES 可 ...

  4. [转]用 jQuery 实现页面滚动(Scroll)效果的完美方法

    转自: http://zww.me/archives/25144 很多博主都写过/转载过用 jQuery 实现页面滚动(Scroll)效果的方法,但目前搜来的方法大都在 Opera 下有个小 Bug: ...

  5. java中使用es精准查询_使用ES简单查询语句须知

    查询样例 {"query": { //1 "bool": { ///2 "must": [{ //3 "query_string& ...

  6. es分页查询重复数据_ES优化 - 巨量数据如何提高查询性能

    问题:如果数据量特别大,如何优化ES的查询性能? 可以从以下几个方面进行思考: File Cache可用的内存: ES的查询严重依赖OS的File Cache,所以说内存分配的内存肯定是越多越好.最理 ...

  7. Es 模糊查询 match,wildcard

    Es 模糊查询的方式 要求: Es查询: 查询工单信息, 输入 "测试",查出 form_name 为字段中有查询出含有符合内容的数据 match:分词模糊查询: 比如" ...

  8. 滚动(scroll)操作的应用

    说明         滚动(scroll) 在LVGL中,滚动的工作原理非常简单,如果对象超出父对象内容区域(即无填充大小),则父对象的空间变为可滚动,任何对象都可滚动. 滚动条为对象的一个部件,通过 ...

  9. ES关键字查询-特殊符号

    项目中ES关键字查询遇到的坑,本来如果在创建关键字字段的时候就应该限制一些特殊符号的输入的,比如限制只能输入字母下划线和数字这种,不用允许输入特殊符号(@,$,*...),结果项目经理不让,说是限制了 ...

最新文章

  1. MPB:农科院牧医所赵圣国组-基于GraftM对功能基因进行物种注释
  2. linux下使用inotify实时监控文件变更,做完整性检查
  3. 68.视图在数据库系统三级结构的哪一级上?
  4. C# 获取文件MD5值的方法
  5. Qt图形界面编程入门(5)
  6. Facebook黄毅博士:像加工艺术品一样构建技术产品
  7. ie6中容器内浮动元素的border边框不完全显示的bug
  8. 数位DP入门题 hdu 2089 hdu 3555
  9. 项目整理-支付宝的支付问题
  10. OpenStack基金会任命马振强为中国区大使
  11. 一些利用开源浏览器核心开发专用浏览器的连接
  12. 2021-CVPR-Inpainting论文导读
  13. 计算机打印东西怎么横向打印机,打印机横向打印怎么设置,打印机不能横向打印...
  14. react之通俗易懂配置less
  15. Browserslist: caniuse-lite is outdated. Please run: npx browserslist@latest --update-db
  16. CSCD(2015-2016年)来源期刊目录中国科学引文数据库
  17. 大数据技术之HFDS
  18. tl wdr5660虚拟服务器,TP-Link TL-WDR5600路由器端口映射怎么设置
  19. python web前端后端页面详解
  20. 推荐系统:冷启动问题【用户冷启动、物品冷启动、系统冷启动】

热门文章

  1. BZOJ4406 WC2016 论战捆竹竿
  2. 品牌赞助公关策划有哪些经典案例?
  3. 计算机毕业设计java+ssm公交站牌广告灯箱管理系统(源码+系统+mysql数据库+Lw文档)
  4. Unity读取Excel表
  5. 多媒体播放器-VLC media player提供下载
  6. 所谓习惯,就是重复次数多到足以自动化的行为
  7. Thinkphp5下微信公众号获取用户信息
  8. Mac小技巧 苹果Mac系统如何删除其他多余的管理员账户
  9. simulink笔记——FM调制解调
  10. python 画k线图_matplotlib画k线图