Elasticsearch 深度分页 search_after

Version: 7.11

默认情况下 from 与size 的参数组合无法获取超过 10,000 的数据. 此限制是由 index.max_result_window 设置的保护措施。
搜索请求通常是覆盖多个分片, 使用 from 与 size 进行分页, 每个分片需要加载符合条件的页以及之前所有页的数据到内存中,
这样会明显的增加内存以及 CPU 的使用. 所以应避免使用 from 和 size 去深度分页或者一次请求大量的数据.

深度分页可以使用 search_after 参数来实现, search_after 是使用上一页中的一组 sort 值来检索下一页的.

官方文档 Paginate search results

FieldSortBuilder timeOrder = new FieldSortBuilder(CRATE_TIME).order(SortOrder.DESC);
// 使用 es 内置的 _id 作为二级排序字段, _id 具有唯一性.
FieldSortBuilder idOrder = new FieldSortBuilder("_id").order(SortOrder.DESC);
List<SortBuilder<FieldSortBuilder>> sorts = Arrays.asList(timeOrder, idOrder);

Object[] searchAfter = null;
boolean isLastPage = false;
List<SearchHit> hitList = new ArrayList<>();
do {
    SearchResponse searchResponse = template.opsForQuery()
        .search(INDEX_NAME, boolQueryBuilder, null, null, sorts, searchAfter, 1000);
    SearchHit[] hits = searchResponse.getHits().getHits();
    int length = hits.length;
    if (length > 0) {
        hitList.addAll(Arrays.asList(hits));
        SearchHit hit = hits[length - 1]; // 获取最后一条记录, 并把 sort 的值赋值给 searchAfter
        searchAfter = hit.getSortValues();
    } else {
        isLastPage = true;
    }
} while (!isLastPage);

 

点击链接加入群聊【互联网技术交流群】:282575808

posted @ 2021-10-22 09:57  景岳  阅读(1912)  评论(0编辑  收藏  举报