欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > es深分页问题解决小记

es深分页问题解决小记

2024/11/30 10:38:58 来源:https://blog.csdn.net/mikelv01/article/details/139806063  浏览:    关键词:es深分页问题解决小记

SpringBoot整合SpringDataElasticsearch

ElasticsearchRestTemplate使用

ElasticSearch的scroll滚动查询以及在Springboot中的使用

ES三种查询

问题描述

在分页查询中,当查询数据总量超过10000时,es为了避免大量数据加载到内存导致内存溢出默认情况下会加限制最大1w条

当数量超过的时候会提示异常:

org.springframework.data.elasticsearch.RestStatusException: Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]; nested exception is ElasticsearchStatusException[Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Result window is too large, from + size must be less than or equal to: [10000] but was [52030]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting.]]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Result window is too large, from + size must be less than or equal to: [10000] but was [52030]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting.]];

解决方案

可以使用滚动查询(Scroll API)来解决这个问题。其实原理也简单,就是将本次查询最后id当作下次查询条件,一直轮询,直到查询没数据就返回。

public void page(Req req) {NativeSearchQuery nsq = new NativeSearchQueryBuilder()//取消es中最大10000条限制.withTrackTotalHits(Boolean.TRUE).withQuery(assemblePageBoolQueryBuilder(req)).withSorts(SortBuilders.fieldSort("created_date").order(SortOrder.DESC)).withPageable(PageRequest.of(req.getPage(), req.getRows())).build();SearchScrollHits<MonitorOrderSearchEsDto> search = elasticsearchRestTemplate.searchScrollStart(60000, nsq, MonitorOrderSearchEsDto.class, ES_INDEX);//滚动id,记录当前查询的终止位置String scrollId = search.getScrollId();//快照在es缓存中保存时长,自定义long scrollTimeInMillis = 60 * 1000;//滚动次数,模拟分页数(page)int scrollTimes = 0;//当滚动查询无数据返回 或 滚动次数大于分页数,不再查询while (search.hasSearchHits() && scrollTimes < req.getPage()) {search = elasticsearchRestTemplate.searchScrollContinue(scrollId, scrollTimeInMillis, MonitorOrderSearchEsDto.class, ES_INDEX);//记录每次的滚动idscrollId = search.getScrollId();scrollTimes = scrollTimes + 1;}//因为es每次滚动查询会生成快照,需要清除当前滚动idelasticsearchRestTemplate.searchScrollClear(Collections.singletonList(scrollId));//业务处理...
}
  • 60000,只是一个示例的时间数据,该参数表明查询结果在es中保存时效时间
  • 需分别调用3个方法 searchScrollStartsearchScrollContinuesearchScrollClear

总结:

  1. 滚动查询是建立在普通查询基础上的
  2. 滚动查询相当于快照,如果在使用scroll进行滚动查询期间有所增删改操作,那么查询结果不会同步最新

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com