Mongodb分组查询

库里的数据

 简单分组查询

      //封装查询条件
        List<AggregationOperation> operations = new ArrayList<>();
        //根据用户id in查询
        operations.add(Aggregation.match(Criteria.where("from").in(ids)));
        //然后分组
        operations.add(Aggregation.group("from").count().as("count"));
        Aggregation aggregation = Aggregation.newAggregation(operations);
        AggregationResults<CustomerStatisticsDTO> aggregateData = imMongoTemplate.aggregate(aggregation, "chat_history", CustomerStatisticsDTO.class);
        List<CustomerStatisticsDTO> data = aggregateData.getMappedResults();
        System.out.println(JSON.toJSONString(data));

            //根据pageName和userId
            Query query = new Query(Criteria.where("pageName").is(TaskTypeEnum.VIEW_SUCCESS_SERVICE.getPageName()).and("userId").is(v));
            //创建时间倒叙 取第一条
            query.with(Sort.by(Sort.Direction.DESC, "createTime")).limit(1);
            CustomerStatisticsDTO statisticsDto = mongoTemplate.findOne(query, CustomerStatisticsDTO.class, "buried_point");

复杂分组查询

库里的数据

 1.根据pageName字段查询和时间区间和格式化时间类型的查询

  //封装查询条件
        List<AggregationOperation> operations = new ArrayList<>();
        //检索pageName字段
        operations.add(Aggregation.match(Criteria.where("pageName").is(TaskTypeEnum.VIEW_SUCCESS_SERVICE.getPageName()).
                //大于等于
                and("createTime").gte(new Date(1638316845000L))));
        //小于等于
        operations.add(Aggregation.match(Criteria.where("createTime").lte(new Date())));
        //date类型 转成字符串 $dateToString 函数
        operations.add(Aggregation.project().andExpression("{$dateToString:{ format:'%Y-%m-%d',date: '$createTime'}}").as("createTime"));
        Aggregation aggregation = Aggregation.newAggregation(operations);
        AggregationResults<CustomerStatisticsDTO> aggregateData = mongoTemplate.aggregate(aggregation, "buried_point", CustomerStatisticsDTO.class);
        System.out.println(JSON.toJSONString(aggregateData.getMappedResults()));
format:需要返回的日期式,日期格式通常为以:

%Y Year (4 digits, zero padded) 0000-9999
%m Month (2 digits, zero padded) 01-12
%d Day of Month (2 digits, zero padded) 01-31
%H Hour (2 digits, zero padded, 24-hour clock) 00-23
%M Minute (2 digits, zero padded) 00-59
%S Second (2 digits, zero padded) 00-60
%L Millisecond (3 digits, zero padded) 000-999
%j Day of year (3 digits, zero padded) 001-366
%w Day of week (1-Sunday, 7-Saturday) 1-7
%U Week of year (2 digits, zero padded) 00-53
%% Percent Character as a Literal


$dateToString 可以替代为

$dayOfYear: 返回该日期是这一年的第几天。(全年366天)
$dayOfMonth: 返回该日期是这一个月的第几天。(1到31)
$dayOfWeek: 返回的是这个周的星期几。(1:星期日,7:星期六)
$year: 返回该日期的年份部分 $month: 返回该日期的月份部分(between 1and12.)
$week: 返回该日期是所在年的第几个星期(between 0and53)
$hour: 返回该日期的小时部分 $minute: 返回该日期的分钟部分
$second: 返回该日期的秒部分(以0到59之间的数字形式返回日期的第二部分,但可以是60来计算闰秒。)
$millisecond:返回该日期的毫秒部分(between 0and999.)

2.先根据pageName字段,然后取时间区间,然后把时间格式化为小时,然后分组,倒叙,求一段时间内的那个小时内用户访问量最大

    //封装查询条件
        List<AggregationOperation> operations = new ArrayList<>();
        //检索pageName字段
        operations.add(Aggregation.match(Criteria.where("pageName").is(TaskTypeEnum.VIEW_SUCCESS_SERVICE.getPageName()).
                //大于等于
                and("createTime").gte(new Date(1638316845000L))));
        //小于等于
        operations.add(Aggregation.match(Criteria.where("createTime").lte(new Date())));
        //只看小时
        operations.add(Aggregation.project().andExpression("{$hour:{date: '$createTime'}}").as("createTime"));
        //分组 之后count求数量
        operations.add(Aggregation.group("createTime").count().as("count"));
        //根据count数量倒叙
        operations.add(Aggregation.sort(Sort.by(Sort.Direction.DESC, "count")));
        //取第一条
        operations.add(Aggregation.limit(1));
        Aggregation aggregation = Aggregation.newAggregation(operations);
        AggregationResults<CustomerStatisticsDTO> aggregateData = mongoTemplate.aggregate(aggregation, "buried_point", CustomerStatisticsDTO.class);
        System.out.println(JSON.toJSONString(aggregateData.getMappedResults()));

3.多字段分组之后结构会发生改变

        //封装查询条件
        List<AggregationOperation> operations = new ArrayList<>();
        //检索pageName字段
        operations.add(Aggregation.match(Criteria.where("pageName").is(TaskTypeEnum.VIEW_SUCCESS_SERVICE.getPageName()).
                //大于等于
                        and("createTime").gte(new Date(1638316845000L))));
        //小于等于
        operations.add(Aggregation.match(Criteria.where("createTime").lte(new Date())));
        //只看小时
        operations.add(Aggregation.project().andInclude("userId").andExpression("{$dateToString:{ format:'%H',date: '$createTime'}}").as("createTimeStr"));
        //分组 之后count求数量
        operations.add(Aggregation.group("createTimeStr", "userId").count().as("count"));
        //重新定义字段
        //operations.add(Aggregation.project("createTimeStr", "userId", "count"));

        Aggregation aggregation = Aggregation.newAggregation(operations);
        AggregationResults<CustomerStatisticsDTO> aggregateData = mongoTemplate.aggregate(aggregation, "buried_point", CustomerStatisticsDTO.class);
        System.out.println(JSON.toJSONString(aggregateData.getMappedResults()));

加上这行代码,就能重新定义列

operations.add(Aggregation.project("createTimeStr", "userId", "count"));

 如图:多出来了两列

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值