如何在Mongoose中聚合嵌入式文档中的字段 [英] How to aggregate fields from embedded documents in Mongoose

查看:62
本文介绍了如何在Mongoose中聚合嵌入式文档中的字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

覆盖模型.

var CoverageSchema = new Schema({
module : String,
source: String,
namespaces: [{
        name: String,
        types: [{
                name: String, 
                functions: [{
                        name: String, 
                        coveredBlocks: Number,
                        notCoveredBlocks: Number
                    }]
            }]
    }]
});

我需要每个级别的CoveredBlocks聚合:

I need coveredBlocks aggregations on every level:

*Module: {moduleBlocksCovered}, // SUM(blocksCovered) GROUP BY module, source
**Namespaces: [{nsBlocksCovered}] // SUM(blocksCovered) GROUP BY module, source, ns
****Types: [{typeBlocksCovered}] // SUM(blocksCovered) BY module, source, ns, type

如何在猫鼬中得到Coverage.aggregate的结果?

How do I get this result with Coverage.aggregate in Mongoose ?

{
module: 'module1',
source: 'source1',
coveredBlocks: 7, // SUM of all functions in module
namespaces:[
     name: 'ns1',
     nsBlocksCovered: 7, // SUM of all functions in namespace
     types:[
     {
         name: 'type1',
         typeBlocksCovered: 7, // SUM(3, 4) of all function in type
         functions[
         {name: 'func1', blocksCovered: 3},
         {name:'func2', blocksCovered: 4}]
     }
     ]
]
}

推荐答案

我的想法是使用$ unwind解构所有内容,然后使用组和投影再次重构文档.

My ideas is to deconstruct everything using $unwind then reconstruct the document back again using group and projection.

aggregate flow:

//deconstruct functions
unwind(namesapces) 
unwind(namespaces.types)
unwind(namespace.types.functions)
//cal typeBlocksCovered
group module&source ,ns,type to sum functions blocksCovered->typeBlocksCovered + push functions back to types
project to transform fields to be easier for next group
// cal nsBlocksCovered
group module&source ,ns to sum typeBlocksCovered -> nsBlocksCovered) + push types back to ns
project to transform fields to be easier for next group
// cal coveredBlocks
group module&source to sum nsBlocksCovered  -> coveredBlocks
project to transform fields to match your mongoose docs

我的示例查询具有mongo shell语法,并且看起来很正常,可能是您使用的是集合名称"Coverage"

My sample query with mongo shell syntax and its seem working , guess is you are using collection name "Coverage"

db.Coverage.aggregate([
    {"$unwind":("$namespaces")}
    ,{"$unwind":("$namespaces.types")}
    ,{"$unwind":("$namespaces.types.functions")}
    ,{"$group": {
        _id: {module:"$module", source:"$source", nsName: "$namespaces.name", typeName : "$namespaces.types.name"}
        , typeBlocksCovered : { $sum : "$namespaces.types.functions.blocksCovered"}
        , functions:{ "$push": "$namespaces.types.functions"}}} 
    ,{"$project" :{module:"$_id.module", source:"$_id.source"
                    ,namespaces:{ 
                        name:"$_id.nsName"
                        ,types : { name: "$_id.typeName",typeBlocksCovered : "$typeBlocksCovered" ,functions: "$functions"}
                    }
                    ,_id:0}}  
    ,{"$group": {
        _id: {module:"$module", source:"$source", nsName: "$namespaces.name"}
        , nsBlocksCovered : { $sum : "$namespaces.types.typeBlocksCovered"}
        , types:{ "$push": "$namespaces.types"}}}
    ,{"$project" :{module:"$_id.module", source:"$_id.source"
                    ,namespaces:{ 
                        name:"$_id.nsName"
                        ,nsBlocksCovered:"$nsBlocksCovered"
                        ,types : "$types"
                    }
                    ,_id:0}}
    ,{"$group": {
        _id: {module:"$module", source:"$source"}
        , coveredBlocks : { $sum : "$namespaces.nsBlocksCovered"}
        , namespaces:{ "$push": "$namespaces"}}}
    ,{"$project" :{module:"$_id.module", source:"$_id.source", coveredBlocks : "$coveredBlocks", namespaces: "$namespaces",_id:0}}       
])

这篇关于如何在Mongoose中聚合嵌入式文档中的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆