一个mongo聚合数据的例子

MongoDB数据聚合实践
本文介绍了一种使用MongoDB进行数据聚合的方法,通过编写特定的JavaScript函数实现按学校和角色分组统计数据,并计算如点赞数、下载数等关键指标。


mongo里每天会记录一些这样的数据,要把这些数据按照时间聚合。


function statisticsSchoolForTimes(nowtime) {
    db.getCollection('all').aggregate(
    [
        {$match:{"time":nowtime}},
        {
            $group:{
                _id:{"schoolId":"$schoolId","userRole":"$userRole"},
                provinceCode:{$first:"$provinceCode"},
                provinceValue:{$first:"$provinceValue"},
                cityValue:{$first:"$cityValue"},
                cityCode:{$first:"$cityCode"},
                countyCode:{$first:"$countyCode"},
                countyValue:{$first:"$countyValue"},
                schoolLevel:{$first:"$schoolLevel"},
                schoolName:{$first:"$schoolName"},
                schoolId:{$first:"$schoolId"},
                time:{$first:"$time"},
                userRole:{$first:"$userRole"}
            }
         }
    ]).forEach(function(x){
            var praiseNum=db.getCollection('all').find({"schoolId":x.schoolId,"time":x.time,"type":"praise","userRole":x.userRole}).count();
            var downloadNum=db.getCollection('all').find({"schoolId":x.schoolId,"time":x.time,"type":"download","userRole":x.userRole}).count();
            var collectionNum=db.getCollection('all').find({"schoolId":x.schoolId,"time":x.time,"type":             "collection","userRole":x.userRole}).count();
            var commentNum=db.getCollection('all').find({"schoolId":x.schoolId,"time":x.time,"type":"comment","userRole":x.userRole}).count();
            var browseNum=db.getCollection('all').find({"schoolId":x.schoolId,"time":x.time,"type":"browse","userRole":x.userRole}).count();
            db.getCollection('school').insert(x);
            db.getCollection('school').update({"schoolId":x.schoolId,"time":x.time,"userRole":x.userRole},{'$set': {'praiseNum': praiseNum,'downloadNum': downloadNum,'collectionNum': collectionNum,'commentNum': commentNum,'browseNum': browseNum}});
        })
}

java里面每天凌晨定时执行这个函数即可

    private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    public void run() {
        try {
        	System.out.println("开始数据统计聚合任务,时间为:"+formatter.format(Calendar.getInstance().getTime()));
        	aggregate();
            System.out.println("结束数据统计聚合任务,时间为:"+formatter.format(Calendar.getInstance().getTime()));
        } catch (Exception e) {
            System.out.println("-------------数据统计聚合任务发生异常--------------"+e.toString());
        }
    }


    public static void aggregate(){
    	System.out.println("开始数据统计聚合任务,时间为:"+formatter.format(Calendar.getInstance().getTime()));
    	MongoUtils mu = new MongoUtils();
		MongoUtils.createMongoClient();
		DB db=mu.getDB(MongoUtils.DATABASE);
		String nowTime = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
		db.eval("statisticsDistrictForTimes('"+nowTime+"')");
		db.eval("statisticsSchoolForTimes('"+nowTime+"')");
		mu.closeConnection();
        System.out.println("结束数据统计聚合任务,时间为:"+formatter.format(Calendar.getInstance().getTime()));
    }


聚合之后的数据是这样的:



MongoDB中,可以使用MongoTemplate进行聚合查询以获取最新的一条数据。以下是一个例子: ```java // 创建聚合管道操作列表 List<AggregationOperation> operations = new ArrayList<>(); // 添加聚合操作,按照时间降序排序并取第一条数据 operations.add(Aggregation.sort(Sort.Direction.DESC, "timestamp")); operations.add(Aggregation.limit(1)); // 执行聚合查询 Aggregation aggregation = Aggregation.newAggregation(operations); AggregationResults<Document> result = mongoTemplate.aggregate(aggregation, "collectionName", Document.class); // 获取查询结果 List<Document> resultList = result.getMappedResults(); Document latestData = resultList.get(0); // 打印最新的一条数据 System.out.println(latestData); ``` 在上述代码中,首先创建一个聚合管道操作列表,并添加了两个聚合操作。sort操作用于按照时间字段降序排序,limit操作用于限制结果只返回一条数据。 然后,使用MongoTemplate的aggregate方法执行聚合查询。其中,Aggregation.newAggregation方法用于创建Aggregation对象,指定了要执行的聚合操作列表和结果的类型。mongoTemplate.aggregate方法执行聚合查询,并将结果存储在AggregationResults对象中。 最后,通过AggregationResults对象的getMappedResults方法获取查询结果的列表,并获取其中的第一条数据作为最新的一条数据。 请注意,上述代码中的"collectionName"需要替换为实际的集合名称。此外,还需要根据实际情况修改代码以适应具体的数据结构和字段名。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值