前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >elasticsearch分页获取数据

elasticsearch分页获取数据

作者头像
johnhuster的分享
发布2022-03-29 14:44:20
1.1K0
发布2022-03-29 14:44:20
举报
文章被收录于专栏:johnhuster

提到elasticsearch分页,可能首先想到的是类似mysql的那种处理方式,传入分页起始值以及每页数据量,es确实提供了类似的处理策略,代码如下:

代码语言:javascript
复制
	@Test
	public void searchFromSize() throws IOException{
		SearchRequest searchRequest = new SearchRequest("sub_bank1120");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        //每页10个数据
		searchSourceBuilder.size(10);
        //起始位置从10开始
		searchSourceBuilder.from(10);
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT); 
		SearchHit[] searchHits = searchResponse.getHits().getHits();
	    for(SearchHit s:searchHits){
	    	println(s.getSourceAsString());
	    }
	}	

但是上述方式有一个严重的缺陷:from和size不能太大,两者之和不能超过index.max_result_window,超过该值就会报

org.elasticsearch.client.ResponseException异常

Result window is too large, from + size must be less than or equal to: [10000] but was [11010]

为什么会使用index.max_result_window来限制搜索深度,因为这需要耗费大量内存,比如from为10000,es会按照一定的顺序从每个分片读取10010个数据,然后取出每个分片中排序前10的数据返回给协调节点,协调节点会将从所有分片节点返回的10条数据再次进行统一排序处理,以此来返回全局排序前10的数据,如果有类似的需要可以使用scroll以及search after来实现超大分页问题,

scroll分页示例代码可以参考:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.8/java-rest-high-search-scroll.html

search after示例可以参考下面代码:

代码语言:javascript
复制
	/**
	 * search after
	 * @throws IOException
	 */
	@Test
	public void searchAfter() throws IOException{
		SearchRequest searchRequest = new SearchRequest("sub_bank1031");
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(QueryBuilders.matchQuery("cityId", "511000"));
		searchSourceBuilder.size(2);
        //id动态映射为text类型,排序不能使用分词的字段,所以这里选择了id的keyword多字段属性
		searchSourceBuilder.sort(new FieldSortBuilder("id.keyword").order(SortOrder.ASC));
		//
		searchRequest.source(searchSourceBuilder);
		SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT); 
		SearchHit[] searchHits = searchResponse.getHits().getHits();
		if(searchHits.length >0){
		    for(SearchHit s:searchHits){
		    	println(s.getSourceAsString());
		    }
		    JSONObject json = JSON.parseObject(searchHits[searchHits.length-1].getSourceAsString());
		    String id = json.getString("id");
		    searchSourceBuilder.searchAfter(new Object[]{id});
		    searchRequest.source(searchSourceBuilder);
		    searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT); 
		    for(SearchHit s:searchHits){
		    	println(s.getSourceAsString());
		    }		    
		}
	}	

下图为索引映射部分截图:

PS:

search after与scroll相比简单些,而且无状态。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/11/20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
Elasticsearch Service
腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档