Javascript 多聚合查询MongoDB

Javascript 多聚合查询MongoDB,javascript,mongodb,mongodb-query,aggregation-framework,Javascript,Mongodb,Mongodb Query,Aggregation Framework,我有以下情况: 收集部门: { "_id" : 0, "name" : "Dep_A_1", "description" : "Department A1" } { "_id" : 1, "name" : "Dep_B_1", "description" : "Department B1" } { "_id" : 2, "name" : "Dep_C_1", "description" : "Department C1" } 收藏技能: { "_id" : 0, "na

我有以下情况:

  • 收集
    部门

    { "_id" : 0, "name" : "Dep_A_1", "description" : "Department A1" }
    { "_id" : 1, "name" : "Dep_B_1", "description" : "Department B1" }
    { "_id" : 2, "name" : "Dep_C_1", "description" : "Department C1" }
    
  • 收藏
    技能

    { 
        "_id" : 0, 
        "name" : "Creativity", 
        "description" : "description", 
        "type" : "soft", 
        "categories" : [ 0, 2 ] 
    }
    
  • 集合
    角色

    { 
        "_id" : 0,
        "name" : "Software Developer Automation and Control",
        "description" : "Automation and Control expert",
        "departments" : [ 0, 2 ],
        "skills" : [ { "_id" : 18, "weight" : 30 } ]
    }
    
我需要这样的结果:

{
    "_id" : 0, 
    "name" : "Software Developer Automation and Control", 
    "description" : "Automation and Control expert",
    "departments" : [ 
        { 
            "_id" : 0, 
            "name" : "Dep_A_1",
            "description" : "Department A1" 
        }, 
        { 
            "_id" : 2, 
            "name" : "Dep_C_1", 
            "description" : "Department C1" 
        }
    ], 
    "skills" : [ 
        {
            "_id" : 0, 
            "name" : "Creativity", 
            "description" : "description", 
            "type" : "soft", 
            "weight" : 30
        }
    ]
}
我需要将
角色.departments
角色.skills
数组替换为
部门
角色
集合中的相应对象。有没有办法查询Mongo并得到这样的结果

无论如何,我使用的是Mongo3.6和Pymango。 谢谢。

只需使用两次:

编辑:现在正确保留了
角色.技能.权重

db.getCollection('roles').aggregate([
    {$unwind: '$skills'},
    {$lookup: {
        from: 'skills',
        localField: 'skills._id',
        foreignField: '_id',
        as: 'skillsInfo'
    }},
    {$unwind: '$skillsInfo'},
    {$addFields: {skills: {$mergeObjects: ['$skills', '$skillsInfo']}}},
    {$project: {skillsInfo: 0}},
    {$group: {
        _id: '$_id',
        name: {$first: '$name'},
        description: {$first: '$description'},
        departments: {$first: '$departments'},
        skills: {$push: '$skills'}
    }},
    {$lookup: {
        from: 'departments',
        localField: 'departments',
        foreignField: '_id',
        as: 'departments'
    }}
])

为了避免成本高昂的
$REWIND
$group
阶段,您可以这样做:

db.roles.aggregate([{
    $lookup: {
        from: 'departments',
        localField: 'departments',
        foreignField: '_id',
        as: 'departments'
    }
}, {
    $lookup: {
        from: 'skills',
        let: {
            "skills": "$skills" // keep a reference to the "skills" field of the current document and make it accessible via "$$skills"
        },
        pipeline: [{
            $match: {
                $expr: {
                    $in: [ "$_id", "$$skills._id" ] // this just does the "joining"
                }
            }
        }, {
            $addFields: { // add a new field
                "weight": { // called "weight"
                    $arrayElemAt: [ // which shall be set to the correct "weight"
                        "$$skills.weight", // that can be found in the "weight" field of the "skills" array
                        { $indexOfArray: [ "$$skills._id", "$_id" ] } // at the position that has the matching "_id" value
                    ]
                }
            }
        }],
        as: 'skills'
    }
}])

到目前为止你试过什么?你能展示一些东西吗?这对部门来说非常有效,但这样我就失去了角色、技能和权重的价值。有解决方案吗?您好,您的答案会产生以下错误:“$arrayElemAt的第二个参数必须是数值,但是对象”您确定您使用的是最新版本的代码吗?我想在我后来添加的“indexOfArray”前面最初缺少了一个
$
。它肯定能在我的机器上工作——我只是再试一次。
db.roles.aggregate([{
    $lookup: {
        from: 'departments',
        localField: 'departments',
        foreignField: '_id',
        as: 'departments'
    }
}, {
    $lookup: {
        from: 'skills',
        let: {
            "skills": "$skills" // keep a reference to the "skills" field of the current document and make it accessible via "$$skills"
        },
        pipeline: [{
            $match: {
                $expr: {
                    $in: [ "$_id", "$$skills._id" ] // this just does the "joining"
                }
            }
        }, {
            $addFields: { // add a new field
                "weight": { // called "weight"
                    $arrayElemAt: [ // which shall be set to the correct "weight"
                        "$$skills.weight", // that can be found in the "weight" field of the "skills" array
                        { $indexOfArray: [ "$$skills._id", "$_id" ] } // at the position that has the matching "_id" value
                    ]
                }
            }
        }],
        as: 'skills'
    }
}])