【背景】
前段时间做统计,我们的平台数据库用的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是常用的管道命令之一:修改输⼊⽂档的结构,如重命名、增加、删除字段、创建计算结果
【总结】
接到需求,进行分析,查询尝试,到解决问题,再到总结知识,相信下次再遇到可以直接用了。