MongoTemplate实现分页查询大量数据及效率优化

2023-03-13  本文已影响0人  南瓜pump
1. 关于分页查询,可以使用Pageable构建条件实现分页查询:
    public IPage<AIBoxDTO> pageRecords(AIBoxCond cond) {
        // 分页参数
        Pageable pageable = PageRequest.of(cond.getCurrent(), cond.getSize());

        // 构造查询条件
        Query query = new Query();

        // 判断是否需要按照报警时间查询
        if (!ObjectUtils.isEmpty(cond.getBeginTime()) && !ObjectUtils.isEmpty(cond.getEndTime())) {
            Criteria criteria = new Criteria();
            criteria.andOperator(Criteria.where("dts").gte(cond.getBeginTime().getTime()), Criteria.where("dts").lte(cond.getEndTime().getTime()));
            query.addCriteria(criteria);
        }
        // 查询总数
        long totalCount = mongoTemplate.count(query, AIBoxDTO.class);

        // 去除photo字段显示,避免数据量过大导致查询失败,要查看图片通过详情接口查询(/flow/api/aibox/getById)
        // query.fields().exclude("photo");

        // 增加分页条件
        query.with(pageable);
        // 按照报警时间排序倒排
        query.with(Sort.by(Sort.Direction.DESC, "dts"));
        List<AIBoxDTO> dtos = mongoTemplate.find(query, AIBoxDTO.class);

        // 构造分页返回
        Page<AIBoxDTO> page = new Page<>(cond.getCurrent(), cond.getSize());
        page.setTotal(totalCount).setRecords(dtos);

        return page;
    }
2. 关于查询效率优化,以上分页查询虽能实现分页功能但是查询效率很低,笔者排查之后发现是mongoTemplate.count()方法查询过慢导致的,查询资料之后优化如下:
    public IPage<AIBoxDTO> pageRecords(AIBoxCond cond) {
        // 分页参数
        Pageable pageable = PageRequest.of(cond.getCurrent(), cond.getSize());

        // 总数
        long totalCount;

        // 构造查询条件
        Query query = new Query();

        // 判断是否需要按照报警时间查询
        if (!ObjectUtils.isEmpty(cond.getBeginTime()) && !ObjectUtils.isEmpty(cond.getEndTime())) {
            Criteria criteria = new Criteria();
            criteria.andOperator(Criteria.where("dts").gte(cond.getBeginTime().getTime()), Criteria.where("dts").lte(cond.getEndTime().getTime()));
            query.addCriteria(criteria);
            // 查询总数,当查询条件不为空时用countDocuments统计数量,并给dts加索引以优化查询速度
            totalCount = mongoTemplate.count(query, AIBoxUploadMsgDTO.class);
        } else {
            // 查询总数,当查询条件为空时用estimatedDocumentCount统计数量以优化查询速度
            totalCount = mongoTemplate.getCollection("aiBoxRecord").estimatedDocumentCount();
        }

        // 去除photo字段显示,避免数据量过大导致查询失败,要查看图片通过详情接口查询(/flow/api/aibox/getById)
        query.fields().exclude("photo");

        // 增加分页条件
        query.with(pageable);
        // 按照报警时间排序倒排
        query.with(Sort.by(Sort.Direction.DESC, "dts"));
        List<AIBoxUploadMsgDTO> dtos = mongoTemplate.find(query, AIBoxUploadMsgDTO.class);

        // 构造分页返回
        Page<AIBoxUploadMsgDTO> page = new Page<>(cond.getCurrent(), cond.getSize());
        page.setTotal(totalCount).setRecords(dtos);

        return page;
    }
上一篇 下一篇

猜你喜欢

热点阅读