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

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

作者: 南瓜pump | 来源:发表于2023-03-13 13:42 被阅读0次
    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()方法查询过慢导致的,查询资料之后优化如下:
    • 首先给查询条件增加索引,在对应的属性上加上@Indexed注解,
    • 如果查询条件不为空,使用countDocuments查询统计数量,
    • 如果查询条件为空,使用estimatedDocumentCount查询统计数量,
    • 另外,可以使用query.fields().exclude()方法去除不需要的字段。
        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;
        }
    

    相关文章

      网友评论

          本文标题:MongoTemplate实现分页查询大量数据及效率优化

          本文链接:https://www.haomeiwen.com/subject/xvscrdtx.html