千家信息网

如何解决ES深度分页问题

发表于:2025-11-09 作者:千家信息网编辑
千家信息网最后更新 2025年11月09日,这篇文章主要介绍"如何解决ES深度分页问题",在日常操作中,相信很多人在如何解决ES深度分页问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何解决ES深度分页问题"
千家信息网最后更新 2025年11月09日如何解决ES深度分页问题

这篇文章主要介绍"如何解决ES深度分页问题",在日常操作中,相信很多人在如何解决ES深度分页问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何解决ES深度分页问题"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

ES深度分页问题:

ES 默认采用的分页方式是 from+ size 的形式,类似于MySQL的分页offset+limit。当请求数据量比较大时,Elasticsearch会对分页做出限制,因为此时性能消耗会很大。例如查询1000条数据,假设我们有5个分片,那么每个shard都需要返回1000条数据给 coordinating node,而 coordinating node 需要接收 5*1000 条数据,进行排序后返回1000条数据给客户端。即使每条数据只有 _doc _id 和 _score,这数据量也很大了,如果请请求量很大的情况下,很容易造成ES的OOM。ES中有个设置index.max_result_window ,默认是10000条数据,如果分页的数据超过第1万条,就拒绝返回结果了。如果集群配置比较好,查询请求量不是特别大,可以适当的放大这个参数。

解决方案:

1:使用scroll遍历

scroll 分为初始化和遍历两步,初始化时将所有符合搜索条件的搜索结果缓存起来,可以想象成快照,在遍历时,从这个快照里取数据,也就是说,在初始化后对索引插入、删除、更新数据都不会影响遍历结果。因此,scroll 并不适合用来做实时搜索,而更适用于后台批处理任务等

API说明:

1)初始化

POST /book/_search?scroll=1m&size=2{"query": { "match_all": {}}}
  1. 遍历

GET /_search/scroll{"scroll": "1m","scroll_id" : "步骤1中查询出来的值"}

使用java RestHighLevelClient代码参考如下:

@Autowiredprivate RestHighLevelClient restHighLevelClient;public Result  scrollSearch(...查询参数){     BoolQueryBuilder queryBuilder.te = QueryBuilders.boolQuery();     //添加自己的搜索条件....     queryBuilder.must(QueryBuilders.termQuery("type", "商品所属分类);     queryBuilder.must(QueryBuilders.matchQuery("name", "商品名称");     //搜索     SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource();     searchSourceBuilder.query(queryBuilder);     //排序     searchSourceBuilder.sort(SortBuilders.fieldSort("order").order(SortOrder.DESC));     //搜索结果     SearchResponse searchResponse = null;     //根据实际情况,判断是多次调用还是一次while遍历查询全部      if (StringUtils.isBlank("scrollId")) {            //首屏            searchSourceBuilder.size("每次查询的条数");            SearchRequest searchRequest = new SearchRequest();            searchRequest.indices("索引名").source(searchSourceBuilder);            searchRequest.scroll(new Scroll(TimeValue.timeValueMinutes(scrollKeepAliveTime)));            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);     } else {            //后续根据上次的id滚动            SearchScrollRequest searchScrollRequest = new SearchScrollRequest("scrollId");            searchScrollRequest.scroll(new Scroll(TimeValue.timeValueMinutes(scrollKeepAliveTime)));            searchResponse = restHighLevelClient.scroll(searchScrollRequest, RequestOptions.DEFAULT);     }             SearchHit[] hits = searchResponse.getHits().getHits();     //根据业务需求,处理搜索结果     GoodsDTO result= handleSearchData(hits);     //scrollId,往下滚动需要使用     String scrollId = searchResponse.getScrollId();     return Result.succcess(result);}

2:使用search after

满足实时获取下一页的文档信息,search_after 分页的方式是根据上一页的最后一条数据来确定下一页的位置,同时在分页请求的过程中,如果有索引数据的增删改,这些变更也会实时的反映到游标上,这种方式是在es-5.X之后才提供的。为了找到每一页最后一条数据,每个文档的排序字段必须有一个全局唯一值使用 _id 就可以了。

API说明:

GET /book/_search{    "query": {"match_all": {}},    "size": 2,    "sort": [{"_id": "desc"}]}GET /book/_search{    "query": {"match_all": {}},    "size": 2,    "search_after": [3],    "sort": [{"_id": "desc"}]}

下一页的数据依赖上一页的最后一条的信息 所以不能跳页

使用java RestHighLevelClient代码参考如下:

@Autowiredprivate RestHighLevelClient restHighLevelClient;public Result  searchAfter(...查询参数){        SearchRequest searchRequest = new SearchRequest(index);        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();        searchSourceBuilder.query(...搜索条件);        searchSourceBuilder.size(1000);        searchSourceBuilder.sort("_id", SortOrder.ASC);        searchSourceBuilder.searchAfter("上一页最后一条数据的id");        searchRequest.source(searchSourceBuilder);        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);        SearchHit[] hits = searchResponse.getHits().getHits();         //根据业务需求,处理搜索结果         GoodsDTO result= handleSearchData(hits);         return Result.succcess(result);}

到此,关于"如何解决ES深度分页问题"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

数据 搜索 查询 问题 结果 深度 搜索结果 学习 很大 参数 实时 方式 条件 索引 上一 排序 业务 代码 信息 商品 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全法施行一周年 h2 数据库聚合函数 学哪个软件开发技术前途好 怎样获得网络服务器时间 金手指数据库编辑器v1.3.9 深圳电视墙服务器生产厂家 惠州西餐厅自助点餐软件开发 显示器和服务器连接不上 网络安全知识竞赛登录注册 无法跟服务器取得安全链接 我的世界中服务器九婴刷新点在哪 项目打成jar包运行到服务器中 想要做软件开发需要哪些技能 pubg体验服服务器慢怎么解决 数据库主数据文件的创建 服务器付费安全软件哪个好 软件开发技术kpi指标 荣达网络技术 天津提供ipfs服务器云主机 数据库逻辑模型举例 华研网络安全研究院 计算机网络技术自测题 access数据库 共享 数据库脚本文件转成txt au插件数据库在哪里 网络安全相关支出包括哪些 项目打成jar包运行到服务器中 云服务器资源管理器打不开 日本官方的专利数据库 软件开发项目保存自定义格式
0