如何在MongoDB中进行内部连接?

Asa*_*ina 8 join mongodb nosql

有可能在MongoDB中做SQL内连接类的东西,我知道有

$查找

在聚合管道中的属性,它相当于SQL中的外连接,但我想做一个类似于内部连接的任务,我有两个三个集合,我需要合并在一起

----User Collection----
db.User.find({})
{
   ID : 1,
   USER_NAME : "John",
   password : "pass"
}
{

   ID : 2,
   USER_NAME : "Andrew",
   PASSWORD : "andrew"
}

---ROLE COLLECTION---
db.ROLE.find({})
{
   ID : 1,
   ROLE_NAME : "admin"
},
{
    ID : 2,
    ROLE_NAME : "staff"
}

---USER_ROLE COLLECTION---
db.USER_ROLE.find({})
{
   ID : 1,
   USER_ID : 1,
   ROLE_ID : 1
}
Run Code Online (Sandbox Code Playgroud)

我有3个以上的集合,我想只提取与用户匹配的文件及其各自的角色而不是所有文件,如何在MongoDB中管理它可以有人给我一个建议吗?

Asa*_*ina 14

我找到了自己的回答

$ unwind完成了这个技巧,随后查询为我工作

    db.USER.aggregate([{
            $lookup: {
                from: "USER_ROLE",
                localField: "ID",
                foreignField: "USER_ID",
                as: "userRole"
            }
        }, {
            $unwind: {
                path: "$userRole",
                preserveNullAndEmptyArrays: false
            }
        }, {
            $lookup: {
                from: "ROLE",
                localField: "userRole.ROLE_ID",
                foreignField: "ID",
                as: "role"
            }
        }, {
            $unwind: {
                path: "$role",
                preserveNullAndEmptyArrays: false
            }
        }, {
            $match: {
                "role.ROLE_NAME": "staff"
            }, {
                $project: {
                    USER_NAME: 1,
                    _id: 0
                }
            }
            ]).pretty()
Run Code Online (Sandbox Code Playgroud)

无论如何,谢谢你的答案


pro*_*r79 11

正如提拉米苏所写,这看起来像架构问题.

您可以通过删除$ lookup返回空数组的文档来进行手动内连接.

....
{$lookup... as myArray},
{$match: {"myArray":{$ne:[]}}},
{$lookup... as myArray2},
{$match: {"myArray2":{$ne:[]}}},
Run Code Online (Sandbox Code Playgroud)

架构变化

我个人会去进行架构更新,如下所示:

db.User.find({})
{
   ID : 1,
   USER_NAME : "John",
   password : "pass"
   roles:[{ID : 1,  ROLE_NAME : "admin"}]
}


db.ROLE.find({})
{
   ID : 1,
   ROLE_NAME : "admin"
},
Run Code Online (Sandbox Code Playgroud)