es分页查询

ES(Elasticsearch)分页查询通常使用 fromsize 参数来控制查询结果的分页。from 用于指定从哪个结果开始,size 用于指定返回多少条记录。

示例查询

假设你想查询 my_index 索引,并且希望分页获取数据:

json

GET /my_index/_search { "from": 0, "size": 10, "query": { "match_all": {} } }

参数解释:

  • from: 表示从第几条记录开始(默认为0,表示从第一条开始)。
  • size: 表示每页返回多少条记录。

分页逻辑:

  • 第一页:from = 0, size = 10(返回从0到9的记录)。
  • 第二页:from = 10, size = 10(返回从10到19的记录)。
  • 第三页:from = 20, size = 10(返回从20到29的记录)。

注意事项:

  1. 当你分页查询时,如果数据量非常大,建议使用search_after进行深分页,它比from/size更高效。
  2. fromsize 使用时会增加查询的开销,特别是在大数据集上。

from size

复制代码
    public List<ResFoodOrderInspectionVO> queryGroupByOrgGroupLocationCode(ReqFoodOrderInspectionVO reqVO) {
        log.info("食用订单巡检表查询条件:{}", reqVO.toString());
        StopWatch stopwatch = new StopWatch();
        stopwatch.start();
        List<ResFoodOrderInspectionVO> resList = Lists.newArrayList();
        SearchRequest searchRequest = new SearchRequest(EsOperateTables.FOOD_ORDER_INSPECTION_V2.getAlias());
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.fetchSource(RES_FBASEFOODORDERINSPEC_FIELDS, null);
//        searchSourceBuilder.size(0);// 设置为0代表不需要取查询到的所有数据,只需要取聚合的相关的数据
        searchSourceBuilder.size(reqVO.getSize());
        searchSourceBuilder.from((reqVO.getPage() - 1) * reqVO.getSize());
        BoolQueryBuilder booleanQuery = QueryBuilders.boolQuery();
        // 组装查询条件
        buildBooleanQuery(booleanQuery, reqVO);
        searchSourceBuilder.query(QueryBuilders.constantScoreQuery(booleanQuery));
        // 分组,统计,排序
        FoodOrderInspectionConvertor.groupCountAgg(searchSourceBuilder, reqVO, foodOrderInspectionDisabled);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            stopwatch.stop();
        } catch (IOException e) {
            log.error(ErrorMsgConstant.FOODORDERINSPECTION_QUERYES_ERROR, e);
            throw new OrderCenterException(ErrorMsgConstant.FOODORDERINSPECTION_QUERYES_ERROR);
        }
        if (Objects.isNull(searchResponse)) {
            return Collections.emptyList();
        }

        Terms terms = searchResponse.getAggregations().get(FoodOrderInspectionConstant.GROUPDIMENSION);
        if (Objects.isNull(terms)) {
            return Collections.emptyList();
        }
        // 包含门店,且按日统计时,需要判断总量,其他场景,总分组量实际不会大于10000,不需要判断
        if (CollectionUtils.isNotEmpty(reqVO.getLocationCodes()) && !reqVO.getGroupMonth() && searchResponse.getHits().getTotalHits() > FoodOrderInspectionConstant.GROUP_RETURN_SIZE) {
            throw new OrderCenterException(ErrorMsgConstant.GROUP_TOTALSIZE_TOOLONG);
        }
        // 组装数据
        for (Terms.Bucket entry : terms.getBuckets()) {
            resList.add(FoodOrderInspectionConvertor.toResVO(entry, reqVO));
        }
        // 取聚合统计后合计
        Map<String, Aggregation> totalMap = searchResponse.getAggregations().getAsMap();
        resList.forEach(v -> {
            v.setResFoodOrderInspectionTotalVO(FoodOrderInspectionConvertor.buildTotal(totalMap));
        });
        log.info("食用订单巡检报表查询耗时:{}", stopwatch.getTotalTimeMillis());
        return resList;
    }

}

searchAfter

java 复制代码
    private SearchRequest buildSearchRequest(EsSchemel esSchemel, QueryBuilder params, int pageSize, String orderBy, String scrollId) {
        if (pageSize > 10000) {
            //fixed:es error,from + size must be less than or equal to: [10000]
            pageSize = 10000;
        }
        SearchRequest searchRequest = new SearchRequest(esSchemel.getIndex());
        searchRequest.types(esSchemel.getType());
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(params);
        //sourceBuilder.from(pageNo - 1);
        sourceBuilder.size(pageSize);
        sourceBuilder.timeout(new TimeValue(30, TimeUnit.SECONDS));
        if (esSchemel.getSelectCols() != null && esSchemel.getSelectCols().length > 0) {
            //性能参数,减少io
            sourceBuilder.fetchSource(esSchemel.getSelectCols(), EXCLUDEFIELDS);
        }
        if (!Strings.isNullOrEmpty(orderBy)) {
            sourceBuilder.sort(new FieldSortBuilder(orderBy).order(SortOrder.DESC));
            if (!Strings.isNullOrEmpty(scrollId)) {
                sourceBuilder.searchAfter(new Object[]{scrollId});
            }
        }
        searchRequest.source(sourceBuilder);
        return searchRequest;
    }
相关推荐
忆~遂愿7 分钟前
CANN ATVOSS 算子库深度解析:基于 Ascend C 模板的 Vector 算子子程序化建模与融合优化机制
大数据·人工智能
玄同76517 分钟前
SQLite + LLM:大模型应用落地的轻量级数据存储方案
jvm·数据库·人工智能·python·语言模型·sqlite·知识图谱
吾日三省吾码19 分钟前
别只会“加索引”了!这 3 个 PostgreSQL 反常识优化,能把性能和成本一起打下来
数据库·postgresql
chian-ocean20 分钟前
百万级图文检索实战:`ops-transformer` + 向量数据库构建语义搜索引擎
数据库·搜索引擎·transformer
小Tomkk39 分钟前
数据库 变更和版本控制管理工具 --Bytebase 安装部署(linux 安装篇)
linux·运维·数据库·ci/cd·bytebase
qq_12498707531 小时前
基于JavaWeb的大学生房屋租赁系统(源码+论文+部署+安装)
java·数据库·人工智能·spring boot·计算机视觉·毕业设计·计算机毕业设计
艾莉丝努力练剑1 小时前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
倒流时光三十年2 小时前
SpringBoot 数据库同步 Elasticsearch 性能优化
数据库·spring boot·elasticsearch
码农小卡拉2 小时前
深入解析Spring Boot文件加载顺序与加载方式
java·数据库·spring boot
怣502 小时前
MySQL多表连接:全外连接、交叉连接与结果集合并详解
数据库·sql