一:ES的存储和查询原理

Elasticsearch中数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回

二:如何分页查询呢?

(1)抛出需求问题
按照一般的查询流程来说,如果我想查询前10条数据:
1 客户端请求发给某个节点
2 节点再转发给某个分片,查询每个分片上的前10条
3 各个分片的查询结果返回给节点,然后再整合数据,提取前10条
4 节点再返回给请求客户端
那么当我想要查询第11条到第20条的数据该怎么办呢?这个时候就用到分页查询了。
(2)两种解决方式
1.第一种from-size"浅"分页
概念:"浅分页”是查的页数比较小;"深分页”是查的比较深。
举个例子:百度最多查询前76页,为什么只有76页,而没有第1万页,假如查询第1万页就是深度分页了。

带着为啥百度只能查询76页的疑问,我们分析下浅分页和深分页的原理是什么?
假设每页大小是10条,查第77页761-770条数据。
浅分页的原理就是要查询每个分片上的前77页的前770条数据,然后不要前760条,只返回761-770的数据。这样其实白白浪费了前760条的查询。

查询的方法如:

{"from" : 760, "size" : 10,"query" : {"term" : { "user" : "yao" }}
}

其中,from定义了目标数据的偏移值,size定义当前返回的事件数目。
默认from为0,size为10,即所有的查询默认仅仅返回前10条数据。
性能问题:做过测试,越往后的分页,执行的效率越低。
通过下图可以看出,刨去一些异常的数据,总体上还是会随着from的增加,消耗时间也会增加。而且数据量越大,效果越明显!

也就是说,分页的偏移值越大,执行分页查询时间就会越长
2.第二种scroll“深”分页
相对于from和size的分页来说,使用scroll可以模拟一个传统数据的游标,记录当前读取的数据条数位置。这个分页的用法,缺点是不实时查询数据,优点是一次性查询大量的数据(甚至是全部的数据)。

因为这个scroll相当于维护了一份当前索引段的快照信息,这个快照信息是你执行这个scroll查询时的快照。**为什么不实时?**因为快照没有更新最新的索引,在这个查询后的任何新索引进来的数据,都不会在这个快照中查询到。但是它相对于from和size,不是查询所有数据然后剔除不要的部分,而是记录一个读取的位置,保证下一次快速继续读取。
看到这里,总结下两者的区别
(1)从查询数据的大小来看。form和size是全量查询数据,然后舍弃掉无用数据;scroll是只查询所需数据,因为它有游标记录了位置。
(2)从查询数据的实时性来看。form和size是实时查询;scroll因为快照没有及时更新最新插入数据的索引,es为查询而生,插入不是强项,所有插入都要构建索引。而快照属于拷贝,拷贝之后有新的数据插入并构建了索引,快照并没有及时重新拷贝新的。
如何选择哪种方式进行分页?
(1)使用上的选择,form和size已经满足大部分的需求。form和size每次只能查询1万条。百度的76页,每页6条只有456条数据。对于平时的业务系统每页10条,能够满足查询1000页了,如果超出了1000页,谁会看超出1000页的数据呢?已经没有业务使用意义了,那么肯定是产品定义错了需求,需要页面加过滤条件,比如时间字段,分多次查询几千页,每次看1000页。

API使用方法如:

curl -XGET 'localhost:9200/twitter/tweet/_search?scroll=1m' -d '
{"query": {"match" : {"title" : "elasticsearch"}}
}

会自动返回一个_scroll_id,通过这个id可以继续查询(实际上这个ID会很长哦!):

curl -XGET ‘localhost:9200/_search/scroll?scroll=1m&scroll_id=c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1’
注意,我在使用1.4版本的ES时,只支持把参数放在URL路径里面,不支持在JSON body中使用。

测试from&size VS scroll的性能
首先呢,需要在java中引入elasticsearch-jar,比如使用maven:
这里重点不是讲ES的使用,ES8.x已经舍弃了TransportClient 客户端的用法,建议使用Java REST Client客户端,本文中还是用的旧的TransportClient ,这不是重点,重点是知道两种分页方式

<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>1.4.4</version>
</dependency>

然后初始化一个client对象:

private static TransportClient client;private static String INDEX = "index_name";private static String TYPE = "type_name";public static TransportClient init(){Settings settings = ImmutableSettings.settingsBuilder().put("client.transport.sniff", true).put("cluster.name", "cluster_name").build();client = new TransportClient(settings).addTransportAddress(new InetSocketTransportAddress("localhost",9300));return client;}public static void main(String[] args) {TransportClient client = init();//这样就可以使用client执行查询了}

然后就是创建两个查询过程了 ,下面是from-size分页的执行代码:

System.out.println("from size 模式启动!");
Date begin = new Date();
long count = client.prepareCount(INDEX).setTypes(TYPE).execute().actionGet().getCount();
SearchRequestBuilder requestBuilder = client.prepareSearch(INDEX).setTypes(TYPE).setQuery(QueryBuilders.matchAllQuery());
for(int i=0,sum=0; sum<count; i++){SearchResponse response = requestBuilder.setFrom(i).setSize(50000).execute().actionGet();sum += response.getHits().hits().length;System.out.println("总量"+count+" 已经查到"+sum);
}
Date end = new Date();
System.out.println("耗时: "+(end.getTime()-begin.getTime()));

下面是scroll分页的执行代码,注意啊!scroll里面的size是相对于每个分片来说的,所以实际返回的数量是:分片的数量*size

System.out.println("scroll 模式启动!");
begin = new Date();
SearchResponse scrollResponse = client.prepareSearch(INDEX).setSearchType(SearchType.SCAN).setSize(10000).setScroll(TimeValue.timeValueMinutes(1)) .execute().actionGet();
count = scrollResponse.getHits().getTotalHits();//第一次不返回数据
for(int i=0,sum=0; sum<count; i++){scrollResponse = client.prepareSearchScroll(scrollResponse.getScrollId())  .setScroll(TimeValue.timeValueMinutes(8))  .execute().actionGet();sum += scrollResponse.getHits().hits().length;System.out.println("总量"+count+" 已经查到"+sum);
}
end = new Date();
System.out.println("耗时: "+(end.getTime()-begin.getTime()));

我这里总的数据有33万多,分别以每页5000,10000,50000的数据量请求,得到如下的执行时间:

可以看到仅仅30万,就相差接近一倍的性能,更何况是如今的大数据环境…因此,如果想要对全量数据进行操作,快换掉fromsize,使用scroll吧!

最后总结:ES更新版本很快,1.x,2.x,3.x,4.x,5.x,6.x,我用的6.x

Elasticsearch——分页查询FromSize VS scroll相关推荐

  1. Elasticsearch分页查询FromSize vs scroll vs search_after

    背景 Elasticsearch 是一个实时的分布式搜索与分析引擎,被广泛用来做全文搜索.结构化搜索.分析.在使用过程中,有一些典型的使用场景,比如分页.遍历等.在使用关系型数据库中,我们被告知要注意 ...

  2. elasticsearch 分页查询实现方案——Top K+归并排序

    elasticsearch 分页查询实现方案 1. from+size 实现分页 from表示从第几行开始,size表示查询多少条文档.from默认为0,size默认为10, 注意:size的大小不能 ...

  3. ElasticSearch分页查询几种方式分析

    ElasticSearch分页查询几种方式分析 1 from+size 语句示例 # from+size浅分页 GET test/_search {"from": 10," ...

  4. Elasticsearch 分页查询聚合分析

    分页查询 关于 Elasticsearch 分页查询,这几个问题经常被问到 问题1:想请问下,一次性获取索引上的某个字段的所有值(100 万左右),除了把 max_result_window 调大 , ...

  5. Elasticsearch分页查询Fromamp;Size VS scroll

    对于ES来说,按照一般的查询流程来说,如果我想查询数据: 1 客户端请求发给某个节点 2 节点转发给个个分片,查询每个分片上的前10条 3 结果返回给节点,整合数据,提取前10条 4 返回给请求客户端 ...

  6. ElasticSearch分页查询的3个坑

    点击上方"Java基基",选择"设为星标" 做积极的人,而不是积极废人! 每天 14:00 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java ...

  7. 解决 Elasticsearch 分页查询记录超过10000时异常

    问题一: 查询结果中 hits.total.value 值最大为10000的限制 解决方法: 请求时设置 "track_total_hits": true Rest 请求设置方法: ...

  8. ElasticSearch分页查询四种解决方案与原理

    当你拼命想完成一件事的时候,你就不再是别人的对手,或者说得更确切一些,别人就不再是你的对手了,不管是谁,只要下了这个决心,他就会立刻觉得增添了无穷的力量,而他的视野也随之开阔了.--<基督山伯爵 ...

  9. ElasticSearch 分页查询及深度分页原理与实现

    查询流程 查询阶段 在初始化查询阶段(query phase),查询被向索引中的每个分片副本(原本或副本)广播.每个分片在本地执行搜索并且建 立了匹配 document 的优先队列(priority ...

最新文章

  1. 推荐搜索系统论文干货集锦
  2. 【干货】Facebook产品经理:高效对接and流程解读
  3. [转载]-如何向妻子解释OOD
  4. Codeforces 724 C. Ray Tracing
  5. 上传文件插件(plupload)
  6. 运用大数据分析开展主动服务
  7. 菜鸟的数学建模之路(五):Logistic模型
  8. 字下挂星星的字体_星星掉了字体下载|星星掉了字体 最新版(TTF格式) 下载 - 巴士下载站...
  9. java文件ftp下载,java ftp下载文件夹内所有文件,java 下载ftp文件夹下所有文件
  10. 合并拆分wim文件命令imagex
  11. 苹果cmsv10仿bt部落天堂简约好看的自适应免费模板
  12. Perl之Spreadsheet::WriteExcel
  13. 全面理解Gradle - 定义Task
  14. it工种分类_什么是运维?运维工种有哪些
  15. 2021-08-15 minikube在阿里云centos系统上的安装实践
  16. Direct3D(D3D)简介
  17. Struts2 学习记录(2)
  18. MySQL数据库(一)——基本介绍
  19. c++ tuple的使用
  20. 安卓融云SDK的使用,会话列表,1v1发起单聊

热门文章

  1. MYSQL —(二)筛选、聚合和分组、查询
  2. 独立后台2.0全新版本微信红包封面抽奖流量主小程序 裂变快 收益高
  3. nodejs微信支付小微商户申请入驻时,如何实现图片上传接口
  4. 老虎证券登陆纳斯达克,CEO巫天华:创业要恪守自己的能力圈...
  5. 基于js的网页计算器实现
  6. 不可忽视的软件测试环境问题
  7. LINUX kernel clock系统,基于内核4.4
  8. 小玩具:知识卡(RFID)
  9. 2019/12/25 学习总结(待填坑)
  10. 数据库理论作业 第八章 29 33