点击这里 > 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}}’.

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐