Как объединить несколько коллекций с помощью $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"
}
Ответы
Ответ 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"
}
}
])