MongoDB跨不同文档的两个数组中的项目总计计数? [英] MongoDB aggregate count of items in two arrays across different documents?

查看:94
本文介绍了MongoDB跨不同文档的两个数组中的项目总计计数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的MongoDB收集模式:

Here is my MongoDB collection schema:

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

我需要对其进行汇总,以便获得以下输出:

I need to aggregate it so I get the following output:

[{
  "_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'} }
}});

但是我得到了以下结果:

But I got the following result:

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

aggregation执行此操作的正确方法是什么?

What is the right way to do this with aggregation?

推荐答案

是的,考虑到存在多个数组,这会有点困难,如果同时尝试这两个数组,则会遇到笛卡尔条件",其中一个arrray将另一个的内容相乘.

Yes this is a bit harder considering that there are multiple arrays, and if you try both at the same time you end up with a "cartesian condition" where one arrray multiplies the contents of the other.

因此,只需在开始时合并数组内容,这可能表明您首先应该如何存储数据:

Therefore, just combine the array content at the beginning, which probably indicates how you should be storing the data in the first place:

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 运算符会将类型"值添加到每个数组的每个项目中.并不是说这里真的很重要,因为所有项目无论如何都应该处理唯一", $setUnion 运算符将每个数组污染"为单个数组.

So via the first $project stage the $map operators are adding the "type" value to each item of each array. Not that it really matters here as all items should process "unique" anyway, the $setUnion operator "contatenates" each array into a singular array.

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

As mentioned earlier, you probably should be storing in this way in the first place.

然后执行 $unwind 后跟 $group ,然后通过 为匹配的类型",将10分别与true/false匹配的内容返回到

Then process $unwind followed by $group, wherein each "pros" and "cons" is then evaluated via $cond to for it's matching "type", either returning 1 or 0 where the match is respectively true/false to the $sum aggregation accumulator.

这为您提供了逻辑匹配",可以根据指定的分组键对聚合操作中的每个类型"进行计数.

This gives you a "logical match" to count each respective "type" within the aggregation operation as per the grouping keys specified.

这篇关于MongoDB跨不同文档的两个数组中的项目总计计数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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