覆盖模型。

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


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

*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


如何在Mongoose中使用Coverage.aggregate获得此结果?

{
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解构所有内容,然后使用group和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”

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}}
])

关于node.js - 如何在Mongoose中聚合嵌入式文档中的字段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28449916/

10-10 10:51