ElasticSearch查询—分页查询详解
2017-12-08 12:35
302 查看
Elasticsearch中数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回。那么,如何实现分页查询呢?
按照一般的查询流程来说,如果我想查询前10条数据:
1)客户端请求发给某个节点
2)节点转发给个个分片,查询每个分片上的前10条
3)结果返回给节点,整合数据,提取前10条
4)返回给请求客户端
那么当我想要查询第10条到第20条的数据该怎么办呢?这个时候就用到分页查询了。
在ElasticSearch中实现分页查询的方式有两种,分别为深度分页(from-size)和快照分页(scroll)
1.深度分页(from-size)
原理很简单,就是查询前20条数据,然后截断前10条,只返回10-20的数据。这样其实白白浪费了前10条的查询。
查询API如下:
其中,from定义了目标数据的偏移值,size定义当前返回的事件数目。默认from为0,size为10,即所有的查询默认仅仅返回前10条数据。
做过测试,越往后的分页,执行的效率越低。也就是说,分页的偏移值越大,执行分页查询时间就会越长!
2. 快照分页(scroll)
相对于from和size的分页来说,使用scroll可以模拟一个传统数据的游标,记录当前读取的文档信息位置。这个分页的用法,不
是为了实时查询数据,而是为了一次性查询大量的数据(甚至是全部的数据)。因为这个scroll相当于维护了一份当前索引段的快照
信息,这个快照信息是你执行这个scroll查询时的快照。在这个查询后的任何新索引进来的数据,都不会在这个快照中查询到。但是
它相对于from和size,不是查询所有数据然后剔除不要的部分,而是记录一个读取的位置,保证下一次快速继续读取。
查询API如下:
相关链接如下:https://www.cnblogs.com/xing901022/archive/2016/03/16/5284902.html
http://www.jianshu.com/p/627887e3eea3
按照一般的查询流程来说,如果我想查询前10条数据:
1)客户端请求发给某个节点
2)节点转发给个个分片,查询每个分片上的前10条
3)结果返回给节点,整合数据,提取前10条
4)返回给请求客户端
那么当我想要查询第10条到第20条的数据该怎么办呢?这个时候就用到分页查询了。
在ElasticSearch中实现分页查询的方式有两种,分别为深度分页(from-size)和快照分页(scroll)
1.深度分页(from-size)
原理很简单,就是查询前20条数据,然后截断前10条,只返回10-20的数据。这样其实白白浪费了前10条的查询。
查询API如下:
{ "from" : 0, "size" : 10, "query" : { "term" : { "user" : "kimchy" } } }
其中,from定义了目标数据的偏移值,size定义当前返回的事件数目。默认from为0,size为10,即所有的查询默认仅仅返回前10条数据。
做过测试,越往后的分页,执行的效率越低。也就是说,分页的偏移值越大,执行分页查询时间就会越长!
2. 快照分页(scroll)
相对于from和size的分页来说,使用scroll可以模拟一个传统数据的游标,记录当前读取的文档信息位置。这个分页的用法,不
是为了实时查询数据,而是为了一次性查询大量的数据(甚至是全部的数据)。因为这个scroll相当于维护了一份当前索引段的快照
信息,这个快照信息是你执行这个scroll查询时的快照。在这个查询后的任何新索引进来的数据,都不会在这个快照中查询到。但是
它相对于from和size,不是查询所有数据然后剔除不要的部分,而是记录一个读取的位置,保证下一次快速继续读取。
查询API如下:
curl -XGET 'localhost:9200/twitter/tweet/_search?scroll=1m' -d ' { "query": { "match" : { "title" : "elasticsearch" } } }该查询会自动返回一个_scroll_id,通过这个id(经过base64编码)可以继续查询。
curl -XGET '集群节点IP:9200/_search/scroll?scroll=1m&scroll_id=c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1'3.java API实现
public class PageQueryInElasticSearch { private static String index = "test_index35"; private static String type = "test_type35"; public static void main(String[] args) { Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name", "contentmanageres") .put("client.transport.sniff", true)// 开启ES嗅探功能,确保集群连上多个节点 .build(); // 创建客户端 TransportClient transportClient = new TransportClient(settings); // 添加es的节点信息,可以添加1个或多个 TransportAddress transportAddress = new InetSocketTransportAddress("172.17.168.96", 9300); transportClient.addTransportAddresses(transportAddress); // 连接到的节点 ImmutableList<DiscoveryNode> connectedNodes = transportClient.connectedNodes(); for (DiscoveryNode discoveryNode : connectedNodes) { System.out.println(discoveryNode.getHostAddress()); } System.out.println("from size 模式启动!"); Date begin = new Date(); long count = transportClient.prepareCount(index).setTypes(type).execute().actionGet().getCount();//获取所有记录 SearchRequestBuilder requestBuilder = transportClient.prepareSearch(index).setTypes(type).setQuery(QueryBuilders.matchAllQuery()); for(int i=0,sum=0; sum<count; i++){ SearchResponse response = requestBuilder.setFrom(i).setSize(5000).execute().actionGet(); sum += response.getHits().hits().length; System.out.println("总量"+count+" 已经查到"+sum); } Date end = new Date(); System.out.println("耗时: "+(end.getTime()-begin.getTime())); System.out.println("scroll 模式启动!"); begin = new Date(); SearchResponse scrollResponse = transportClient.prepareSearch(index) .setSearchType(SearchType.SCAN) //在ES 5.x版本中不存在SearchType.SCAN用法,可以用addSort(SortBuilders.fieldSort("_doc")) .setSize(1000) //实际返回的数量为size*index的主分片个数(在ES 5.x版本中,返回的数据量就是参数中指定的数据量) .setScroll(TimeValue.timeValueMinutes(1)) .execute().actionGet(); count = scrollResponse.getHits().getTotalHits();//获取所有记录,第一次不返回数据(在ES 5.x版本中,第一次有数据返回) for(int sum=0; sum<count; ){ scrollResponse = transportClient.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())); } }
相关链接如下:https://www.cnblogs.com/xing901022/archive/2016/03/16/5284902.html
http://www.jianshu.com/p/627887e3eea3
相关文章推荐
- 分页查询详解
- ElasticSearch第四步-查询详解
- 详解Oracle的几种分页查询语句
- MySQL详解----------海量数据分页查询优化
- elasticsearch 查询数据 | 分页查询
- Elasticsearch(查询详解)
- elasticsearch 分页查询实现方案——Top K+归并排序
- MySQL详解(19)----------海量数据分页查询优化
- ElasticSearch常用的基本查询语句详解
- Elasticsearch使用scroll进行分页查询
- ElasticSearch学习 - (七)查询详解
- 详解Oracle的几种分页查询语句
- Hibernate实现分页和综合查询详解
- Hibernate(十七)Hibernate实现分页和综合查询详解
- 详解Oracle和SQLServer的分页查询
- 利用Spring MVC+Mybatis实现Mysql分页数据查询的过程详解
- Java通过mongo-java-driver-3.0+分页查询mongodb详解
- Java程序员从笨鸟到菜鸟之(六十九)细谈Hibernate(十七)Hibernate实现分页和综合查询详解
- Java程序员从笨鸟到菜鸟之(六十九)细谈Hibernate(十七)Hibernate实现分页和综合查询详解
- elasticsearch 分页 (from+size)(scroll scan) (search after) 详解-->解决深分页 (持续更新)