如何在Mongoose中embedded文档中的字段

覆盖模型。

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

我需要在各个层面上进行覆盖块集合:

 *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解构所有的东西,然后使用组和投影重新构造文档。

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