mongoTemplate结合Criteria实现分页、模糊、二级嵌套和时间范围查询等
点击这里 > Java实现MongoDB分页查询以及优化方案设计@Transactionalpublic Result<PageResult<SubjectInfo>> list(SubjectInfoDTO subjectInfoDTO){Criteria criteria = new Criteria();// 模糊查询if (ObjectUtils.isNotE
点击这里 > Java实现MongoDB分页查询以及优化方案设计
@Transactional
public Result<PageResult<SubjectInfo>> list(SubjectInfoDTO subjectInfoDTO){
Criteria criteria = new Criteria();
// 模糊查询
if (ObjectUtils.isNotEmpty(subjectInfoDTO.getTitle())) {
criteria.and("title").regex(subjectInfoDTO.getTitle());
}
// Criteria支持二级嵌套查询
if (ObjectUtils.isNotEmpty(subjectInfoDTO.getLabelId())) {
criteria.and("labels.labelId").is(subjectInfoDTO.getLabelId());
}
if (ObjectUtils.isNotEmpty(subjectInfoDTO.getStyleId())) {
criteria.and("styles.styleId").is(subjectInfoDTO.getStyleId());
}
// Criteria支持时间范围查询
// 但注意只能有一个createTime字段作为查询条件
if (ObjectUtils.isNotEmpty(subjectInfoDTO.getStartTime())
&& ObjectUtils.isEmpty(subjectInfoDTO.getEndTime())) {
criteria.and("createTime").gte(subjectInfoDTO.getStartTime());
}
if (ObjectUtils.isEmpty(subjectInfoDTO.getStartTime())
&& ObjectUtils.isNotEmpty(subjectInfoDTO.getEndTime())) {
criteria.and("createTime").lte(subjectInfoDTO.getEndTime());
}
if (ObjectUtils.isNotEmpty(subjectInfoDTO.getStartTime())
&& ObjectUtils.isNotEmpty(subjectInfoDTO.getEndTime())) {
criteria.and("createTime").gte(subjectInfoDTO.getStartTime())
.lte(subjectInfoDTO.getEndTime());
}
// 设置排序
Sort sort = Sort.by(Sort.Direction.ASC,"sort")
.and(Sort.by(Sort.Direction.DESC, "createTime"));
Query query = new Query(criteria).with(sort);
// 由于使用二级嵌套查询,所以这里不能直接使用mongoTemplate的count方法
// mongoTemplate.count()算出总数为0
int count = subjectInfoDao.list(query).size();
// 分页条件
SpringDataPageable pageable = new SpringDataPageable();
pageable.setPageNumber(subjectInfoDTO.getPageNum());
pageable.setPageSize(subjectInfoDTO.getPageSize());
pageable.setSort(sort);
List<SubjectInfo> list = subjectInfoDao.list(query.with(pageable));
PageResult<SubjectInfo> pageResult = new PageResult<>();
pageResult.setTotal(count);
pageResult.setList(list);
return new Result<PageResult<SubjectInfo>>().ok(pageResult);
}
如何理解上面说到Criteria支持时间范围查询,但是只能有一个createTime字段作为查询条件?
以下是小编测试时首次写的代码:
if (ObjectUtils.isNotEmpty(subjectInfoDTO.getStartTime())) {
criteria.and("createTime").gte(subjectInfoDTO.getStartTime());
}
if (ObjectUtils.isNotEmpty(subjectInfoDTO.getEndTime())) {
criteria.and("createTime").lte(subjectInfoDTO.getEndTime());
}
假设如果两个查询条件都不为空,既选择了开始时间,又选择了结束时间
此时criteria语句就变成了
criteria.and(“createTime”).gte(subjectInfoDTO.getStartTime()).and(“createTime”).lte(subjectInfoDTO.getEndTime())
以MySql或Oracle的思维去写范围查询就是
Between A and B 相当于x > A and x < B
但是Mongo这里的criteria不支持这样的写法,只能有一个x,否则会报以下错误
org.springframework.data.mongodb.InvalidMongoDbApiUsageException: Due to limitations of the org.bson.Document, you can’t add a second ‘createTime’ expression specified as ‘createTime : Document{{KaTeX parse error: Expected ‘EOF’, got ‘}’ at position 33: …:00:00 CST 2021}̲}’. Criteria al…gte=Mon Sep 20 00:00:00 CST 2021}}’.
更多推荐
所有评论(0)