在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有几种 ...
随机推荐
- web 打印功能
在项目开发中有时候会碰到要求打印页面中的数据的功能需求.需求原因主要有两点吧,一是需要打印的数据只是页面的一部分即页面的区域打印,比如只需要打印页面中表格里面选中的数据等,二是需要打印出来的样式和页面 ...
- Linux 下文件压缩与解压命令详解
tar 命令 -c 建立压缩档案 -x 解压 -t 查看内容 -r 向压缩归档文件末尾追加文件 -u 更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中 ...
- 浅谈css蒙版效果
我们进网站浏览时经常看到当鼠标悬浮在图片上或者某一个地方时,会出现一层朦胧现象覆盖着悬浮位置,简单的理解为“蒙版效果”.下面简单列举实现过程: HTML: CSS:
- 微信小程序INC自增自减MUL自乘问题
今天使用到微信小程序云开发中的数据库自增字段问题出现了错误 Uncaught (in promise) ReferenceError: _ is not defined 官方给出的INC方法文档 db ...
- 11 非阻塞套接字与IO多路复用(进阶)
1.非阻塞套接字 第一部分 基本IO模型 1.普通套接字实现的服务端的缺陷 一次只能服务一个客户端! 2.普通套接字实现的服务端的瓶颈!!! accept阻塞! 在没有新的套接字来之前,不能处理已经建 ...
- Typora -- 书写即美学
#Typora -- 书写即美学 ##基本快捷键--需要在所见即所想界面进行输入 加粗 Ctrl + B 加粗 斜体 Ctrl + I 斜体 下划线 Ctrl + U 下划线 删除线 Ctrl + S ...
- R语言学习笔记(三):零碎知识点(1-10)
1--c() c表示"连接"(concatenate). 在R中向量是连续存储的,因此不能插入或删除元素. 2--seq() seq()的特殊用法,可以用在for循环里for(i ...
- 【Leetcode】413. Arithmetic Slices
Description A sequence of number is called arithmetic if it consists of at least three elements and ...
- loj136 (最小瓶颈路,多次询问)
题目描述 给定一个包含 n nn 个节点和 m mm 条边的图,每条边有一个权值.你的任务是回答 k kk 个询问,每个询问包含两个正整数 s ss 和 t tt 表示起点和终点,要求寻找从 s ss ...
- git之解决冲突
前面几次使用git,一直对于冲突的这个问题不是很理解,感觉有些时候就会产生冲突,在此记录一下解决冲突的流程 1.git bash上面冲突显示 2.在idea上面可以看到冲突的文件 3.去解决冲突 4. ...