Подтвердить что ты не робот

Как объединить несколько коллекций с помощью $lookup mongodb

Я хочу объединить более двух коллекций, используя метод aggregate $lookup. можно ли присоединиться? сообщите мне, если это возможно. Дайте мне пример. Здесь у меня есть три коллекции:

"пользователи"

{    
"_id" : ObjectId("5684f3c454b1fd6926c324fd"),
    "email" : "[email protected]",
    "userId" : "AD",
    "userName" : "admin"
}

"UserInfo"

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

"UserRole"

{
    "_id" : ObjectId("56d82612b63f1c31cf906003"),
    "userId" : "AD",
    "role" : "admin"
}
4b9b3361

Ответ 1

На самом деле вы можете связать несколько этапов поиска. Основываясь на именах коллекций, разделяемых 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 не должен быть реляционным, но он полезен.

Ответ 2

Функция соединения поддерживается Mongodb 3.2 и более поздними версиями. Вы можете использовать объединения, используя запрос aggregate.
Вы можете сделать это, используя приведенный ниже пример:

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" : "[email protected]",
    "userName" : "admin",
    "userPhone" : "0000000000",
    "role" : "admin"
}

Надеюсь, это поможет вам или кому-то еще.

Спасибо

Ответ 3

Согласно документации, $lookup может присоединиться только к одной внешней коллекции.

Что вы можете сделать, это объединить userInfo и userRole в один сборник, поскольку приведенный пример основан на реляционной схеме БД. Mongo - это база данных noSQL, и для этого требуется другой подход для управления документами.

Ниже приведен двухэтапный запрос, который объединяет userInfo с userRole - создание новой временной коллекции, используемой в последнем запросе для отображения комбинированных данных. В последнем запросе есть опция использования $out и создания новой коллекции с объединенными данными для последующего использования.

создавать коллекции

db.sivaUser.insert(
{    
    "_id" : ObjectId("5684f3c454b1fd6926c324fd"),
        "email" : "[email protected]",
        "userId" : "AD",
        "userName" : "admin"
})

//"userinfo"
db.sivaUserInfo.insert(
{
    "_id" : ObjectId("56d82612b63f1c31cf906003"),
    "userId" : "AD",
    "phone" : "0000000000"
})

//"userrole"
db.sivaUserRole.insert(
{
    "_id" : ObjectId("56d82612b63f1c31cf906003"),
    "userId" : "AD",
    "role" : "admin"
})

"присоединить" все: -)

db.sivaUserInfo.aggregate([
    {$lookup:
        {
           from: "sivaUserRole",
           localField: "userId",
           foreignField: "userId",
           as: "userRole"
        }
    },
    {
        $unwind:"$userRole"
    },
    {
        $project:{
            "_id":1,
            "userId" : 1,
            "phone" : 1,
            "role" :"$userRole.role"
        }
    },
    {
        $out:"sivaUserTmp"
    }
])


db.sivaUserTmp.aggregate([
    {$lookup:
        {
           from: "sivaUser",
           localField: "userId",
           foreignField: "userId",
           as: "user"
        }
    },
    {
        $unwind:"$user"
    },
    {
        $project:{
            "_id":1,
            "userId" : 1,
            "phone" : 1,
            "role" :1,
            "email" : "$user.email",
            "userName" : "$user.userName"
        }
    }
])