我想使用聚合$ lookup在MongoDB中加入两个以上的集合。有可能加入吗?给我一些例子。
这里我有三个系列:
“用户”
{
"_id" : ObjectId("5684f3c454b1fd6926c324fd"),
"email" : "admin@gmail.com",
"userId" : "AD",
"userName" : "admin"
}
“用户信息”
{
"_id" : ObjectId("56d82612b63f1c31cf906003"),
"userId" : "AD",
"phone" : "0000000000"
}
“的UserRole”
{
"_id" : ObjectId("56d82612b63f1c31cf906003"),
"userId" : "AD",
"role" : "admin"
}
答案 0 :(得分:52)
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"
}
希望这会对你或其他人有所帮助。
由于
答案 1 :(得分:30)
您实际上可以链接多个$ 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并不意味着是关系型的,但它很有用。
答案 2 :(得分:11)
根据documentation,$ lookup只能加入一个外部集合。
您可以做的是将userInfo
和userRole
合并到一个集合中,例如,基于关系数据库架构。 Mongo是noSQL数据库 - 这需要不同的文档管理方法。
请查看以下两步查询,该查询将userInfo与userRole结合使用 - 创建在上次查询中使用的新临时集合以显示组合数据。 在上一个查询中,有一个选项可以使用$ out并使用合并数据创建新集合供以后使用。
创建集合
db.sivaUser.insert(
{
"_id" : ObjectId("5684f3c454b1fd6926c324fd"),
"email" : "admin@gmail.com",
"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"
}
}
])
答案 3 :(得分:1)
首先添加集合,然后对这些集合应用查找。不要使用$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"
}
] }
谢谢。
答案 4 :(得分:0)
我不明白您为什么与userId有关系,为什么不使用ObjectId来关联两个文档? 问候。