【背景】
前段时间做统计,我们的平台数据库用的mongodb,其中有一个统计需求如下:需要查询每个用户的转码个数(对应的素材,每个素材可能有多个转码)
【过程】
第一步:数据结构截图如下(计算transcodeIds的大小当成每行数据的一个基数,然后再按照用户id进行聚合):
第二步:mongodb原始命令聚合语句查询以及对应效果截图如下(我用的mongodb可视化工具为NoSQL Manager):
db.material.aggregate({ "$match": { "transcodeIds": { $exists: true } } }, { "$project": { "userId": "$cuserId", "sizeOfColors": { "$size": "$transcodeIds" } } },{ "$group": { "_id": "$userId", "sum": { "$sum": "$sizeOfColors" } } })
第三步:具体java代码编写:
public List<Map<String, Object>> findMaterialTransCodeNum(Long startTime, Long endTime) { List<Document> group = Arrays.asList( new Document("$match", new Document("ctimeStamp", new Document("$gte", startTime) .append("$lt", endTime) ) .append("appCode", "QMTNRK_YUNSHI") ), new Document("$project", new Document("userId", "$cuserId") .append("companyId", "$companyId") .append("departmentId", "$departmentId") .append("companyGroup", "$companyGroup") .append("transcodeNum", new Document("$size", "$transcodeIds")) ), new Document("$group", new Document("_id", new Document("userId", "$userId") .append("companyId", "$companyId") .append("departmentId", "$departmentId") .append("companyGroup", "$companyGroup") ).append("transcodeTotal", new Document("$sum", "$transcodeNum")) ) ); return basicDao.aggregate("material", group); }
【原理知识】
聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果
语法:db.集合名称.aggregate({管道:{表达式}})
$project是常用的管道命令之一:修改输⼊⽂档的结构,如重命名、增加、删除字段、创建计算结果
【总结】
接到需求,进行分析,查询尝试,到解决问题,再到总结知识,相信下次再遇到可以直接用了。