java 使用mongoTemplate 按月分组、聚合的实现 (要求返回非分组字段)

一.需求

统计当前用户过去一年中每个月新增联系人(联系人表存储在mongoDB)

二.分析:

根据createTime 中的月分组,聚合返回字段有:用户id,分组月份,该月记录条数

三:mongo 查询语句

在这里插入图片描述

说明:
$project:映射,查询的字段,1显示,0不显示
$match:过滤,查询条件(相当于sql中的where)
$group:分组,这里用到了 mongo 自带的 $month函数,可以根据createTime中的月分组
注意
分页、排序等语句可以在后面累加;
映射,过滤,分组,分页,排序等有顺序,顺序可以改变,下层在上层的基础上处理数据(管道);
三.java mongoTemplate实现
public AggregationResults<ContactMember> findContactMemberGroupMonth(Date date,Integer userId){
        //查询条件
        Criteria criteria=new Criteria();
        //封装查询日期,gte大于等于
        criteria.and("createTime").gte(date);
        //分组对象
        Aggregation aggregation=Aggregation.newAggregation(
                //添加过滤条件
                Aggregation.match(criteria),
                //查询字段,andExpression(xx).as(yy) 表示将查询字段中的yy替换为xx
                //这里用到了 month函数,需要替换
                Aggregation.project("createTime","userId").andExpression("{$month: '$createTime'}").as("createTime"),
                //根据createTime分组
                //first为 当前列聚合时取多条数据中的第一条
                Aggregation.group("createTime").first("createTime").as("monthNum").count().as("monthCount").first("userId").as("userId")
        );
        //本项目根据userId进行了分表,所以对mongoTemplate进行了封装
        //底层调用 mongoTemplate.aggregate(aggregate, colName, ContactMember.class);
        return super.aggregateResult(aggregation,userId);

    }
四.测试
 @Test
    public void testFindContactMemberGroupMonth(){
        Calendar instance = Calendar.getInstance();
        //过去一年
        instance.add(Calendar.YEAR,-1);
        AggregationResults<ContactMember> groupMonth = contactMemberService.findContactMemberGroupMonth(instance.getTime(),15);
        System.out.println("test123:"+groupMonth.getMappedResults().size());
        System.out.println("test124:"+groupMonth.getMappedResults().get(0));
    }
测试通过(用户id为15的用户10月增加的联系人有5个,和数据库查询结果一致),打印结果:
test123:2
test124:ContactMember{id='10', listId=null, userId=15, email='null', phone='null', name='null', createTime=null, updateTime=null, properties=null, grade='null', importBatchNo='null', tags=null, monthCount=5, monthNum=10}
补充

关于分组和聚合

分组指的是将满足相同条件的数据变为一条(组)数据
比如createTime 创建时间为 2020年的11月有10条数据,若根据createTime 为2020年11月分组,分组后createTime字段唯一,其他字段不一定唯一,其他字段怎么显示呢?这里要用到聚合函数
聚合指的是多个数据如何取值
常见的聚合函数有:sum(求和),max(取最大值),min(最小值),avg(平均值),first(第一个),last(最后一个),count(记录条数)等
本例聚合的所有userId都相同,所以使用first函数即可

mongoDB文档:https://docs.mongodb.com/v2.4/reference/operator/aggregation/project/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值