$lookup
主要功能 是将每个输入待处理的文档,经过$lookup 阶段的处理,输出的新文档中会包含一个新生成的数组列(户名可根据需要命名新key的名字 )。数组列存放的数据 是 来自 被Join 集合的适配文档,如果没有,集合为空(即 为[ ])
基本语法
{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
as: <output array field>
}
}语法的解释说明
| 语法值 | 解释说明 |
| 同一个数据库下等待被Join的集合。 |
| 源集合中的match值,如果输入的集合中,某文档没有 localField 这个Key(Field),在处理的过程中,会默认为此文档含 有 localField:null的键值对。 |
| 待Join的集合的match值,如果待Join的集合中,文档没有foreignField 值,在处理的过程中,会默认为此文档含有 foreignField:null的键值对。 |
| 为输出文档的新增值命名。如果输入的集合中已存在该值,则会覆盖掉, |
上案例 (案例来自于群里一个小伙伴的需求)
有两个表,分别是comment(评论表) 和 user(表)
comment
{
"_id" : ObjectId("5ec5e48b7f7fa92fe266d246"),
"content" : "测试",
"reply" : [
{
"content" : "回复1",
"userId" : ObjectId("5ec5e4c37f7fa92fe266d27e")
},
{
"content" : "回复2",
"userId" : ObjectId("5ec5e4ca7f7fa92fe266d285")
},
{
"content" : "回复3",
"userId" : ObjectId("5ec5e4dd7f7fa92fe266d290")
}
]
}user
/* 1 */
{
"_id" : ObjectId("5ec5e4c37f7fa92fe266d27e"),
"name" : "u1"
}
/* 2 */
{
"_id" : ObjectId("5ec5e4ca7f7fa92fe266d285"),
"name" : "u2"
}
/* 3 */
{
"_id" : ObjectId("5ec5e4dd7f7fa92fe266d290"),
"name" : "u3"
}目标: 需要在comment 表中 关联到user,并输出用户的名称
效果
{
"_id" : ObjectId("5ec5e48b7f7fa92fe266d246"),
"content" : "测试",
"reply" : [
{
"content" : "回复1",
"userId" : ObjectId("5ec5e4c37f7fa92fe266d27e"),
"user" : "u1"
},
{
"content" : "回复2",
"userId" : ObjectId("5ec5e4ca7f7fa92fe266d285"),
"user" : "u2"
},
{
"content" : "回复3",
"userId" : ObjectId("5ec5e4dd7f7fa92fe266d290"),
"user" : "u3"
}
]
}实现语句
db.comment.aggregate([
{
$unwind: '$reply' // 首先拆分了reply这个数组
},
{
$lookup: {
from: 'user', // 从哪个Schema中查询
localField: 'reply.userId', // 本地关联的字段
foreignField: '_id', // user中用的关联字段
as: 'userInfo' // 查询到所有user后放入的字段名,这个是自定义的,是个数组类型。
}
},
{
$unwind:'$userInfo' //因为lookup 关联到的数据会返回的是数组,所以继续拆分一下(这里看个人需要)
},
{
// 按照_id 分组
$group:{
_id:'$_id',
content:{$first:'$content'},
reply:{
$push:{
'content':'$reply.content',
'userId':'$reply.userId',
'user':'$userInfo.name'
}
}
}
}
])这样就可实现需要的效果,MongoDB的聚合查询 是能够实现很多效果的。以上效果只是平常会经常用到的。