[mongoDB] MongoTemplate实现分组聚合分页倒序条件查询

背景:

统计参加活动的用户总分排名信息
条件:
1、限制前一千名;
2、用户的战绩总分必须达到一千分;
3、时间不能超过XXXX,超过此时间获得的得分不计入排名计算中;
4、不允许并列一千,如分数相同,取先达到一千分的用户;
5、需要返回用户在没有超过指定时间之前一共玩了多少次游戏;
6、用户的战绩数据存储在mongoDB。

战绩信息存储结构:

{
    "_id" : NumberLong(2111050000447937),
    "activityId" : NumberLong(5),
    "userId" : NumberLong(2111030000471143),
    "score" : 36,
    "isDeleted" : 0,
    "createUserId" : NumberLong(0),
    "createTime" : NumberLong(1636079718181),
    "updateTime" : NumberLong(1636079738181),
    "updateUserId" : NumberLong(0)
}

实现:

limit:限制前多少名,此场景中为1000;
endTime:进入总分计算的战绩数据创建的最大时间;
minScore:至少需要多少分,此场景中为1000。

public List<UserRankScoreModel> queryUserPeriodRankAndSumScoreByEndTime(Integer limit, Date endTime, Integer minScore) {
        Aggregation aggregation = Aggregation.newAggregation(
                // 条件一:必须要转类型,否则会查不到; lte:小于等于
                Aggregation.match(Criteria.where("createTime").lte(endTime.getTime())),
                // 分组
                // first:返回字段; as:给返回的数据起别名; 
                Aggregation.group("userId").first("userId").as("userId").count().as("gameNum")
                        .sum("score").as("sumScore").max("createTime").as("maxTime"),
                // 条件二:gte:大于等于
                Aggregation.match(Criteria.where("sumScore").gte(Long.valueOf(minScore))),
                // 排序
                Aggregation.sort(Sort.Direction.DESC, "sumScore").and(Sort.Direction.ASC, "maxTime"),
                // 分页 skip:从哪里开始(不包括起点),limit:显示多少条数据
                Aggregation.skip(0L),
                Aggregation.limit(limit));
        // user_activity_score:collection; UserRankScoreModel:接收返回数据的model   
        AggregationResults<UserRankScoreModel> userRankScoreModels
                = mongoTemplate.aggregate(aggregation, "user_activity_score", UserRankScoreModel.class);
        return userRankScoreModels.getMappedResults();
    }
  • UserRankScoreModel.java:
public class UserRankScoreModel {
    /**
     * 用户id
     */
    private Long userId;

    /**
     * 游戏次数
     */
    private Integer gameNum;

    /**
     * 游戏总分
     */
    private Integer sumScore;

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public Integer getGameNum() {
        return gameNum;
    }

    public void setGameNum(Integer gameNum) {
        this.gameNum = gameNum;
    }

    public Integer getSumScore() {
        return sumScore;
    }

    public void setSumScore(Integer sumScore) {
        this.sumScore = sumScore;
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值