springboot+mongodb+分页排序bug

项目场景:

项目场景:最近项目上因为数据量上亿的问题,上了mongodb,主要是用于日志的存储,并设定了过期时间。mongodb分页排序的坑。。。


问题描述

但是mongodb自带的分页效果使用不理想,如果是结合排序,只能在当前页面排序,而不是排序后分页,最后发现,是排序与分页的先后问题导致的。

@Override
	public void run() {
		List<AggregationOperation> operations = new ArrayList<>();
        operations.add(MongoUtils.match("deleted", false));
        operations.add(MongoUtils.match("memberId", memberId));

        //分组前先按时间倒序,这里划重点,排序必须在分页的前面,否则会导致排序只对当前页面有效
        operations.add(Aggregation.sort(Sort.Direction.DESC, "createTime"));

        //分组(去重) 使用mongoTemplate.findDistinct去重,不支持排序
        operations.add(Aggregation.group("dynamicId").first("dynamicId").as("dynamicId").first("createTime").as("createTime"));

        //分组后再按时间倒序一次
        operations.add(Aggregation.sort(Sort.Direction.DESC, "createTime"));

        //只取dynamicId字段
        operations.add(Aggregation.project("dynamicId"));

        //总数,划重点,分页必须在 总数统计 totalCount 的后面,否则会导致排序也只对当前页面有效
        Long totalCount = repositoryOps.getTotalCount(operations, "comment", DynamicIdVO.class);

        //分页参数
        operations.add(Aggregation.skip((long) pagerVO.getPageMG() * pagerVO.getLimit()));
        operations.add(Aggregation.limit(pagerVO.getLimit()));
	}
		Aggregation aggregation = Aggregation.newAggregation(operations);
        AggregationResults<DynamicIdVO> results = mongoTemplate.aggregate(aggregation, "comment", DynamicIdVO.class);

原因分析:

mongodb的排序分页是按照流形式去处理数据的,如果是先分页再排序,会导致数据只取前10条,然后在这10条数据里面排序,也就对应前端的效果是排序只对当前页面有效。包括如果使用了统计的方法,如果分页方法在此之前,也会导致先分页在排序的情况出现。因为如果使用了流,分页也会同步使用,尽量在使用流处理之前不分页。


解决方案:

分页必须放在排序后面,并且如果有统计总数的方法,分页也必须在这个后面。即mongodb如果需要分页的操作,分页必须放在最后面,后面接上查询操作即可。其他mongodb数据库的任何操作,必须在此之前完成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值