在es中用scroll查询与completableFuture
一般而言,es返回数据的上限是10000条,如果超过这个数量,就必须使用scroll查询。
所谓scroll查询就类似DBMS中的游标,或者快照吧,利用查询条件,在第一次查询时,在所有的结果上形成了一个快照,然后再分批分次的读取出来。
要完成一个scroll查询分两个阶段:
阶段一:带查询参数
POST /twitter/_search?scroll=1m
{
"size": ,
"query": {
"match" : {
"title" : "elasticsearch"
}
}
}
这个查询条件比较简单,只是示意。
关键是有两点:1.post路径中的scroll关键字,指明是一个scroll查询;2,scroll=1m意味着查询结果数据在es的服务器有效期是一分钟。
在查询结果的返回值中会带有一个scroll id的参数,这个参数在第二次查询的时候需要。
阶段二:不带参数查询
POST /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}
这个查询请求中,会带上第一次请求得到的scroll_id这个字段。
然后循环往复,第三次查询需要带上第二次查询返回的scroll_id,以此类推,就这个例子而言,当判断返回的数据条数小于100条的时候,就可以结束请求了。
使用scroll查询的两个优势是:
1.无论查询的数据量是多大,都能够查询成功。
2.准确反映了第一次查询当时的查询结果,第一次查询之后的查询请求不会包含新的数据。
但也有一个缺点:
1.因为查询的递进的,第二次依赖于第一次,第三次依赖于第二次,所以如果数据量很多,查询的耗时就比较长。
如何解决耗时长这个问题了?就不能使用scroll来查询了,使用常规的查询,但是启用多线程去查。
GET /_search
{
"query" : {
"term" : { "user" : "kimchy" }
}
}
加入在常规的查询中有timestamp这样的自动,我们可以预先对timestamp进行划分,比如分出10份,当然前提是我们假设数据在时间上是均匀的,然后每个时间切分启用一个线程去查询。在java中有completableFuture能够比较好的支持这种查询场景。
CompletableFuture<JSONArray>[] futures = (CompletableFuture<JSONArray>[]) new CompletableFuture[count];
for (int i = ; i < count; i++) {
CompletableFuture<JSONArray> future = CompletableFuture.
supplyAsync(new JSONAarrySupplier(this.queryString,timestamp[i])
.exceptionally(ex -> {
logger.error(ex.getMessage());
return null;});
futures[i] = future;
}
CompletableFuture<List<JSONArray>> allFuture = myAllOf(futures);
result = allFuture.get();
如上述,在一开始建立了一个future数组,然后根据时间切片,构建查询请求,并放入completableFuture中。
在最后调用get方法,拿到所有线程执行完的结果。
这里有一个点要注意,就是completableFuture.allOf方法本身返回的是void,如果我们的future是有返回值的话,就不能直接调用java自身提供的,需要改下一下,如上其实调用了下面的方法:
public static CompletableFuture<List<JSONArray>> myAllOf(CompletableFuture<?>... futures) {
return CompletableFuture.allOf(futures)
.thenApply(x -> Arrays.stream(futures)
.map(f -> (JSONArray) f.join())
.collect(toList())
).exceptionally(ex -> {
logger.error(ex.getMessage());
return null;});
}
这个方法中实现了返回值的转换。
这种多线程的查询,相对于scroll去查询,在网络不是瓶颈的前提下,性能还是有很大提升。
综上所述:
1.如果对时间不敏感,还是推荐使用scroll查询,毕竟反映了查询时间点的实际情况。
2.如果对时间敏感,则需要合理挑选查询分片条件,形成合理的多线程查询。
参考https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html
在es中用scroll查询与completableFuture的更多相关文章
- es实战之查询大量数据
背景 项目中已提供海量日志数据的多维实时查询,客户提出新需求:将数据导出. 将数据导出分两步: 查询大量数据 将数据生成文件并下载 本文主要探讨第一步,在es中查询大量数据或者说查询大数据集. es支 ...
- ES系列十二、ES的scroll Api及分页实例
1.官方api 1.Scroll概念 Version:6.1 英文原文地址:Scroll 当一个搜索请求返回单页结果时,可以使用 scroll API 检索体积大量(甚至全部)结果,这和在传统数据库中 ...
- 【Elasticsearch】ES中时间查询报错:Caused by: ElasticsearchParseException[failed to parse date field [Sun Dec 31 16:00:00 UTC 2017] with format [yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis]];
ES中时间查询报错:Caused by: ElasticsearchParseException[failed to parse date field [Sun Dec 31 16:00:00 UTC ...
- SQL中的LIKE中用参数化查询
今天终于学会怎么在like中用参数化查询啦..哈哈..再也不用担心sql注入了...
- order by中用子查询排序
今天有个需求是对一个列表排序,但是排序字段是在另一个表中,不想用关联查询,就想能否直接在order by中用子查询,后来找到一个还挺好使.记录如下. 排序语句如下: select * from mai ...
- ES 调优查询亿级数据毫秒级返回!怎么做到的?--文件系统缓存
一道面试题的引入: 如果面试的时候碰到这样一个面试题:ElasticSearch(以下简称ES) 在数据量很大的情况下(数十亿级别)如何提高查询效率? 这个问题说白了,就是看你有没有实际用过 ES,因 ...
- ES 07 - Elasticsearch查询文档的六种方法
目录 1 Query String Search(查询串检索) 2 Query DSL(ES特定语法检索) 3 Query Filter(过滤检索) 4 Full Text Search(全文检索) ...
- Elasticsearch利用scroll查询获取所有数据
Elasticsearch有两种分页方式,一种是通过from和size条件来实现,但是该方法开销比较大,另一种是利用scroll来实现,通过scroll来实现分页获取所有的数据,下面是利用python ...
- ES开启慢查询日志
默认情况,慢日志是不开启的.要开启它,需要定义具体动作(query,fetch 还是 index),你期望的事件记录等级( WARN.INFO.DEBUG.TRACE 等),以及时间阈值. es有几种 ...
随机推荐
- window.location.href 跳转无历史记录
需求:从页面a单点登录跳至页面b,在页面b里做判断符合条件后location.href至c页面 问题:在页面c中点击返回按钮页面回到了a,正常情况下应该回到页面b 原因:在当前页面的 onload 事 ...
- C++最接近整数的浮点运算
Function return ceil 不小于给定值的最接近整数值 floor 不大于给定值的最接近整数 trunc (C++11) 绝对值不大于给定值的最接近整数 round(C++11) 最接近 ...
- 小程序swiper不显示图片
按照文档上的代码运行后,发现图片不显示 解决办法: app.wxss文件 align-items: center;这句话删除了,运行 OK!
- 安装mysqlclient报OSError: mysql_config not found
输入命令: :~$ pip install mysqlclient 报错: Collecting mysqlclient Using cached https://files.pythonhosted ...
- QQ群排名优化到霸屏的策略怎么做?
谈起QQ群排名霸屏,首先要弄清楚概念,有些刚接触QQ群的朋友可能不太了解,所谓的QQ群排名霸屏,就是指当你的客户群体搜索QQ群某个关键词时,出现在QQ群搜索结果前面的群,全部或者大部分都是我们自己的群 ...
- docker使用命令汇总
docker命令 docker ps 容器列表 docker ps -a 所有容器列表,包含未运行的容器 docker image ls 镜像列表 docker logs -f xxx 容器日志 do ...
- Java——英文字母---18.10.11
package lianxi;import java.io.*;import java.util.Scanner;public class file{ public static void main ...
- Python的import导入与时间
一.模块与包 模块,在Python可理解为对应于一个文件.在创建了一个脚本文件后,定义了某些函数和变量.你在其他需要这些功能的文件中,导入这模块,就可重用这些函数和变量.一般用module_name. ...
- 深入浅出 Webpack
深入浅出 Webpack 评价 Webpack 凭借强大的功能与良好的使用体验,已经成为目前最流行,社区最活跃的打包工具,是现代 Web 开发必须掌握的技能之一.作者结合自身的实战经验,介绍了 Web ...
- OSI七层模型加协议
OSI七层网络模型 TCP/IP四层概念模型 对应网络协议 应用层(Application) 应用层 HTTP.TFTP, FTP, NFS, WAIS.SMTP 表示层(Presentation) ...