Java中MongoDB分页查询总结

对于 mongodb 数据库,和 mysql 类似,也有自带的分页 api,其实直接调用 api,也可以实现 mongodb 的分页,主要 api 就是两个:

query.skip((pageNum - 1) * pageSize);
query.limit(pageSize);

其中:pageNo:当前页,pageSize:页大小

但是当数据量多了的时候,mongodb 再使用这种方式去做分页,查询效率就会变得很慢,主要原因是 mongodb 自带的 skip() 方法的问题,跳跃查询导致虽然做了分页,但还是会使数据查询效率低下。

主要原理思路:

条件查询 + 排序 + 限制返回记录。
边查询,边排序,排序之后,抽取第一次分页中的最后一条记录,作为第二次分页的条件,进行条件查询,以此类推…

假设现在要给一个 Title 类做分页查询,一开始还是传统想法,必须要有“当前页”和“页大小”这两个参数:

public List<Title> getTitleList(int pageNo, int pageSize, long startTime, long endTime) {
        // 如果有其他条件,先构造Criteria,比如
        Criteria criteria = Criteria.where("createTime").gte(startTime).lte(endTime);
        // 构造查询query,通过_id排序,此处id如果保存mongo时自动生成,下面查询时需要转化成ObjectId,如果自己生成需要可以排序
        Query query = Query.query(criteria).with(Sort.by(Sort.Direction.DESC, "_id"));
        if (pageNo != 1) {
            // number参数是为了查上一页的最后一条数据
            int number = (pageNo - 1) * pageSize;
            query.limit(number);
            List<Title> titles = mongoTemplate.find(query, Title.class);

            // 获取最后一条数据
            Title title = titles.get(titles.size() - 1);

            // 取到上一页的最后一条数据id,当作条件查询接下来的数据
            String id = title.getId();
            ObjectId objectId = new ObjectId(id);   // 此处id如果保存mongo时自动生成,查询时需要转化成ObjectId
            query.addCriteria(Criteria.where("_id").lt(objectId));
        }
        // 页大小重新赋值,覆盖number参数
        query.limit(pageSize);
        
        List<Title> titleList = mongoTemplate.find(query, Title.class);

        return  titleList;
    }

其实就是不要使用 mongodb 自带的 skip() 这个方法,转而使用 sort() 排序和 limit() 限制数据大小这两个方法,通过排序,让数据每次从上一页的最后一条开始起做查询,再限制每次返回的总数据大小即可!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值