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;
}
网友评论