【问题标题】:Group nested inner array in mongoose在猫鼬中分组嵌套内部数组
【发布时间】:2017-02-12 06:07:25
【问题描述】:

我的 mongoDb 内容如下:

[{
"_id": {
    "$oid": "57c6699711bd6a0976cabe8a"
},
"ID": "1111",
"FullName": "AAA",
"Category": [
    {
        "CategoryId": {
            "$oid": "57c66ebedcba0f63c1ceea51"
        },
        "_id": {
            "$oid": "57e38a8ad190ea1100649798"
        },
        "Value": [
            {
                "Name": ""
            }
        ]
    },
    {
        "CategoryId": {
            "$oid": "57c3df061eb1e59d3959cc40"
        },
        "_id": {
            "$oid": "57e38a8ad190ea1100649797"
        },
        "Value": [
            [
                "111",
                "XXXX",
                "2005"
            ],
            [
                "1212",
                "YYYY",
                "2000"
            ],
            [
                "232323",
                "ZZZZZ",
                "1999"
            ]
        ]
    }
]
},{
    "_id": {
        "$oid": "57c6699711bd6a0976cabe8a"
    },
    "ID": "1111",
    "FullName": "BBB",
    "Category": [
        {
            "CategoryId": {
                "$oid": "57c66ebedcba0f63c1ceea51"
            },
            "_id": {
                "$oid": "57e38a8ad190ea1100649798"
            },
            "Value": [
                {
                    "Name": ""
                }
            ]
        },
        {
            "CategoryId": {
                "$oid": "57c3df061eb1e59d3959cc40"
            },
            "_id": {
                "$oid": "57e38a8ad190ea1100649797"
            },
            "Value": [
                [
                    "4444",
                    "XXXX",
                    "2005"
                ],
                [
                    "7777",
                    "GGGG",
                    "2000"
                ],
                [
                    "8888",
                    "ZZZZZ",
                    "1999"
                ]
            ]
        }
    ]
}]

这里我有一个名为“ResumeCategory”的数组,其中包含具有不同类别 ID 的对象。

我需要 1. 选择 id 为 '57c3df061eb1e59d3959cc40' 的类别 2.上面选择的类别包含值作为数组 3.从值数组中,我必须根据第二个值对元素进行分组,并且需要获取用户名列表

例如输出:

[{
    'CategoryName': 'XXXX',
    'Users': ['AAA', 'BBB']
},
{
    'CategoryName': 'YYYY',
    'Users': ['AAA']
},
{
    'CategoryName': 'ZZZZZ',
    'Users': ['AAA', 'BBB']
},
{
    'CategoryName': 'GGGG',
    'Users': ['BBB']
}]

我尝试使用聚合函数进行分组,如下所示:

resume.aggregate([
  {$match: {'Category.CategoryId': new ObjectId('57c3df191eb1e59d3959cc43')}},
  {$unwind: '$Category'},
  {$unwind: '$Category.Value'},
  {$match: {'Category.CategoryId': new ObjectId('57c3df191eb1e59d3959cc43')}},
  {$group: { _id: '$Category.Value', count: {$sum: 1}}},
  {$project: {'_id':0, TagValue: '$_id',count: '$count'}}
],function(err, resData){
        res.send(resData);
});

从上面的查询中,它是基于值数组分组的。它将具有三个元素的数组分组。任何人都可以帮助根据内部数组值(单个元素,即 value[1])对值进行分组并获得所需的结果。

提前致谢。

【问题讨论】:

    标签: angularjs arrays node.js mongodb mongoose


    【解决方案1】:

    您可以在项目阶段使用$arrayElemAt(3.2版本中引入)选择数组中的第二个元素。

    db.resume.aggregate([
                            {"$unwind":"$Category"}, 
                            {"$match":{"Category.CategoryId" :ObjectId("57c3df061eb1e59d3959cc40")}}, 
                            {"$unwind":"$Category.Value"}, 
                            {"$project":{"FullName":1, "secondVal" : {"$arrayElemAt": ["$Category.Value",1]} }}, 
                            {"$group":{"_id":"$secondVal", "Users":{"$addToSet":"$FullName"}}}, 
                            {"$project":{"CategoryName":"$_id", "_id": 0, "Users":1}}
                        ])
    

    样本输出:

    { "Users" : [ "AAA", "BBB" ], "CategoryName" : "XXXX" }
    { "Users" : [ "AAA" ], "CategoryName" : "YYYY" }
    { "Users" : [ "BBB" ], "CategoryName" : "GGGG" }
    { "Users" : [ "AAA", "BBB" ], "CategoryName" : "ZZZZZ" }
    

    【讨论】:

    • 嗨..我收到错误为'invalid operator $arrayElemAt'。我的 MongoDb 版本 - 3.0.12...这是版本问题吗.. 如果是这样,在 3.0.12 版本中相当于 '$arrayElemAt'
    • 运算符 $arrayElemAt' 是在 3.2 版中引入的。因此,它不适用于 3.0 版。
    • 在 3.0.12 mongodb 版本中是否有 '$arrayElemAt' 的等价物???
    • 我已经升级了我的 mongodb 版本并且“$arrayElemAt”正在工作.. 但是它获取了所有类别但我只需要 id 匹配 '57c3df061eb1e59d3959cc40' 的类别.. 我如何在里面包含这个条件“$项目”
    • @user3211705:如我的回答所示,您可以在 $unwind 之后使用 $match 来限制 ID 为 57c3df061eb1e59d3959cc40 的类别。
    【解决方案2】:

    您只需要 $unwind "Category.Value" 字段两次,因为它有双重嵌套数组:

    resume.aggregate([
        { "$match": { "Category.CategoryId": "57c3df061eb1e59d3959cc40" } },
        { "$unwind": "$Category" },
        { "$match": { "Category.CategoryId": "57c3df061eb1e59d3959cc40" } },    
        { "$unwind": "$Category.Value" },// <-- unwind twice
        { 
            "$unwind": {
                "path": "$Category.Value",
                "includeArrayIndex": "idx" 
            }
        },
        { "$match": { "idx": 1 } },
        {
            "$group": {
                "_id": "$Category.Value",
                "Users": { "$push": "$FullName" },
                "count": { "$sum": 1 }
            }
        },
        { "$project": { "_id": 0, "CategoryName": "$_id", "Users": 1, "count": 1 } } 
    ], function(err, resData){
        res.send(resData);
    });
    

    【讨论】:

    • 上面的示例使用数组中的第一个值对数据进行分组。我应该如何使用第二个值进行分组??? IE。值[1]..
    • 你用的是哪个mongodb版本?
    • 我已将我的 mongoDb 版本从 3.0.12 升级到 3.2.10
    • 您可以尝试使用 $unwind 运算符包含一个额外的字段,该字段包含数组元素索引,然后过滤该索引上的文档,如上面的更新。
    猜你喜欢
    • 2018-10-30
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多