MongoDB——聚合数组大小做统计

【背景】

    前段时间做统计,我们的平台数据库用的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是常用的管道命令之一:修改输⼊⽂档的结构,如重命名、增加、删除字段、创建计算结果

【总结】

   接到需求,进行分析,查询尝试,到解决问题,再到总结知识,相信下次再遇到可以直接用了。