如何在mongodb中使用$lookup连接多个集合

如何在mongodb中使用$lookup连接多个集合,mongodb,join,mongodb-query,Mongodb,Join,Mongodb Query,我想使用聚合$lookup连接MongoDB中的两个以上集合。可以加入吗?给我举几个例子 我这里有三个收藏: 用户: { "_id" : ObjectId("5684f3c454b1fd6926c324fd"), "email" : "admin@gmail.com", "userId" : "AD", "userName" : "admin" } userinfo: { "_id" : ObjectId("56d82612b63f1c31cf9

我想使用聚合
$lookup
连接MongoDB中的两个以上集合。可以加入吗?给我举几个例子

我这里有三个收藏:

用户

{    
    "_id" : ObjectId("5684f3c454b1fd6926c324fd"),
    "email" : "admin@gmail.com",
    "userId" : "AD",
    "userName" : "admin"
}
userinfo

{
    "_id" : ObjectId("56d82612b63f1c31cf906003"),
    "userId" : "AD",
    "phone" : "0000000000"
}
userrole

{
    "_id" : ObjectId("56d82612b63f1c31cf906003"),
    "userId" : "AD",
    "role" : "admin"
}
根据该方法,$lookup只能加入一个外部集合

您可以将
userInfo
userRole
组合到一个集合中,所提供的示例基于关系数据库模式。Mongo是noSQL数据库,这需要不同的文档管理方法

请查找下面的两步查询,它将userInfo与userRole结合在一起-创建上次查询中使用的新临时集合以显示组合数据。 在最后一个查询中,有一个选项可以使用$out并使用合并的数据创建新集合以供以后使用

创建集合

“加入”他们所有人:-)


实际上,您可以链接多个$lookup阶段。根据profesor79共享的集合名称,您可以执行以下操作:

db.sivaUserInfo.aggregate([
    {
        $lookup: {
           from: "sivaUserRole",
           localField: "userId",
           foreignField: "userId",
           as: "userRole"
        }
    },
    {
        $unwind: "$userRole"
    },
    {
        $lookup: {
            from: "sivaUserInfo",
            localField: "userId",
            foreignField: "userId",
            as: "userInfo"
        }
    },
    {
        $unwind: "$userInfo"
    }
])
这将返回以下结构:

{
    "_id" : ObjectId("56d82612b63f1c31cf906003"),
    "userId" : "AD",
    "phone" : "0000000000",
    "userRole" : {
        "_id" : ObjectId("56d82612b63f1c31cf906003"),
        "userId" : "AD",
        "role" : "admin"
    },
    "userInfo" : {
        "_id" : ObjectId("56d82612b63f1c31cf906003"),
        "userId" : "AD",
        "phone" : "0000000000"
    }
}

这可能被认为是一种反模式,因为MongoDB并不意味着是关系型的,但它很有用。

MongoDB 3.2及更高版本支持的连接功能。您可以通过使用聚合查询来使用联接。
您可以使用以下示例执行此操作:

db.users.aggregate([

    // Join with user_info table
    {
        $lookup:{
            from: "userinfo",       // other table name
            localField: "userId",   // name of users table field
            foreignField: "userId", // name of userinfo table field
            as: "user_info"         // alias for userinfo table
        }
    },
    {   $unwind:"$user_info" },     // $unwind used for getting data in object or for one record only

    // Join with user_role table
    {
        $lookup:{
            from: "userrole", 
            localField: "userId", 
            foreignField: "userId",
            as: "user_role"
        }
    },
    {   $unwind:"$user_role" },

    // define some conditions here 
    {
        $match:{
            $and:[{"userName" : "admin"}]
        }
    },

    // define which fields are you want to fetch
    {   
        $project:{
            _id : 1,
            email : 1,
            userName : 1,
            userPhone : "$user_info.phone",
            role : "$user_role.role",
        } 
    }
]);
这将产生如下结果:

{
    "_id" : ObjectId("5684f3c454b1fd6926c324fd"),
    "email" : "admin@gmail.com",
    "userName" : "admin",
    "userPhone" : "0000000000",
    "role" : "admin"
}
希望这能帮助你或其他人


谢谢

首先添加集合,然后对这些集合应用查找。不要使用
$unwind
as unwind将简单地分离每个集合的所有文档。因此,应用简单查找,然后使用
$project
进行投影。 以下是mongoDB查询:

db.userInfo.aggregate([
    {
        $lookup: {
           from: "userRole",
           localField: "userId",
           foreignField: "userId",
           as: "userRole"
        }
    },
    {
        $lookup: {
            from: "userInfo",
            localField: "userId",
            foreignField: "userId",
            as: "userInfo"
        }
    },
    {$project: {
        "_id":0,
        "userRole._id":0,
        "userInfo._id":0
        }
        } ])
以下是输出:

/* 1 */ {
    "userId" : "AD",
    "phone" : "0000000000",
    "userRole" : [ 
        {
            "userId" : "AD",
            "role" : "admin"
        }
    ],
    "userInfo" : [ 
        {
            "userId" : "AD",
            "phone" : "0000000000"
        }
    ] }

谢谢。

如果我们想将userinfo显示为arry in用户角色,该怎么办?如何做到这一点如果您希望数组中的数据来自其他表,而不仅仅是从该表中删除$unwind,则意味着从查询中删除“{$unwind:$user_role”}”,以便从user_role表中获取数组中的数据,这对我非常有帮助;特别是在projectionHi,Amit中使用$unwind和子对象引用。这看起来不错,但并没有解决我的问题。这里的链接是请给出一个响应:在两个联接表的查询中尝试$unwind@azEnItHHey Amit,maybee你能回答一个关于你漂亮的Answer的后续问题吗?->您好,教授,您的代码看起来不错,但没有解决我的问题我提供了我的问题链接请帮助我:有人知道这句话是否仍然正确:
$lookup只能加入一个外部集合
?我在文档链接中没有发现任何限制。谢谢如果集合中有多个文档,那么所有文档都将显示在数组中。非常感谢您的回答。这个回答帮助我理解了聚合。你救了我一天
db.userInfo.aggregate([
    {
        $lookup: {
           from: "userRole",
           localField: "userId",
           foreignField: "userId",
           as: "userRole"
        }
    },
    {
        $lookup: {
            from: "userInfo",
            localField: "userId",
            foreignField: "userId",
            as: "userInfo"
        }
    },
    {$project: {
        "_id":0,
        "userRole._id":0,
        "userInfo._id":0
        }
        } ])
/* 1 */ {
    "userId" : "AD",
    "phone" : "0000000000",
    "userRole" : [ 
        {
            "userId" : "AD",
            "role" : "admin"
        }
    ],
    "userInfo" : [ 
        {
            "userId" : "AD",
            "phone" : "0000000000"
        }
    ] }