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”,或者返回1
或0
,其中匹配分别是true/false
到$sum
汇总累加器。
这为您提供了一个“逻辑匹配”,根据指定的分组键,对聚合操作中的每个“types”进行计数。