MongoDB在两个数组中的不同文档中的项目聚合计数?

这是我的MongoDB集合模式:

company: String model: String cons: [String] // array of tags that were marked as "cons" pros: [String] // array of tags that were marked as "pros" 

我需要将它聚合,所以我得到以下输出:

 [{ "_id": { "company": "Lenovo", "model": "T400" }, "tags": { tag: "SomeTag" pros: 124 // number of times, "SomeTag" tag was found in "pros" array in `Lenovo T400` cons: 345 // number of times, "SomeTag" tag was found in "cons" array in `Lenovo T400` } }...] 

我试图做到以下几点:

 var aggParams = {}; aggParams.push({ $unwind: '$cons' }); aggParams.push({ $unwind: '$pros' }); aggParams.push({$group: { _id: { company: '$company', model: '$model', consTag: '$cons' }, consTagCount: { $sum: 1 } }}); aggParams.push({$group: { _id: { company: '$_id.company', model: '$_id.model', prosTag: '$pros' }, prosTagCount: { $sum: 1 } }}); aggParams.push({$group: { _id: { company:'$_id.company', model: '$_id.model' }, tags: { $push: { tag: { $or: ['$_id.consTag', '$_id.prosTag'] }, cons: '$consTagCount', pros: '$prosTagCount'} } }}); 

但是我得到了以下结果:

 { "_id": { "company": "Lenovo", "model": "T400" }, "tags": [ { "tag": false, "pros": 7 } ] } 

什么是aggregation做到这一点的正确方法?

是的,考虑到有多个数组,如果你同时尝试这两个数组,你最终会得到一个“笛卡尔条件”,在这个条件下,一个数组乘以另一个数组的内容。

因此,只需在开始处合并数组内容,这可能指示您应如何将数据存储在第一位:

 Model.aggregate( [ { "$project": { "company": 1, "model": 1, "data": { "$setUnion": [ { "$map": { "input": "$pros", "as": "pro", "in": { "type": { "$literal": "pro" }, "value": "$$pro" } }}, { "$map": { "input": "$cons", "as": "con", "in": { "type": { "$literal": "con" }, "value": "$$con" } }} ] } }}, { "$unwind": "$data" } { "$group": { "_id": { "company": "$company", "model": "$model", "tag": "$data.value" }, "pros": { "$sum": { "$cond": [ { "$eq": [ "$data.type", "pro" ] }, 1, 0 ] } }, "cons": { "$sum": { "$cond": [ { "$eq": [ "$data.type", "con" ] }, 1, 0 ] } } } ], function(err,result) { } ) 

因此,通过第一个$project阶段, $map操作符将“type”值添加到每个数组的每个项目中。 不是说这里真的很重要,因为所有的项目都应该处理“唯一的”, $setUnion运算符将每个数组“连接”到一个单一的数组中。

如前所述,您可能应该首先以这种方式进行存储。

然后处理$unwind然后是$group ,其中每个“专业人员”和“缺点”然后通过$cond评估为匹配“types”,或者返回10 ,其中匹配分别是true/false$sum汇总累加器。

这为您提供了一个“逻辑匹配”,根据指定的分组键,对聚合操作中的每个“types”进行计数。