前序:
关系型数据库有表连接功能,那么NOSQL有吗?MongoDB有吗?很高兴3.2版本出现了
尽管提供了表连接功能,但是官方还是建议尽量使用内嵌文档的结构来减少表连接的使用
今天介绍的是$lookup, 类似于关系型数据库中的left outer join,
语法:
db.collection.aggregate([{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
as: <output array field>
}
}])
当然$lookup只是一个方法,是被用于aggregate聚合函数当中去的,具体的aggregate()函数的用法,我会另外起一篇来介绍
因为是类似左连接查询,所以肯定要确定哪个是左表,哪个是右表,以及用哪个字段来进行表连接
参数说明:
from: 需要去连接的collection,也就是右表的表名
localField:需要去进行连接的左表的字段名
foreignField: 右表(from参数后的那个collection)的字段名,可以与左表的字段名(localField)不一样,但是数据类型必须一致
as: 形成的新的数组的名称,为什么叫数组呢?你看一下后面的例子就知道了
验证:
两个collection分别是order 和 Info,数据结构如下
我们基于order表的item字段进行联表查询,也就是以order为左表(基准表),Info为右表(附表)
结果如下:
结果集是将order表中的所有数据列出,再添加上连接表Info中对应的数据(紫色,红色部分)
{
"_id" : 1,
"item" : "Jack",
"price" : 12,
"Info_doc" : [
{
"_id" : 1,
"name" : "Jack",
"city" : "Tianjin",
"sex" : 1
}
]
},
/* 2 */
{
"_id" : 2,
"item" : "Johnny",
"price" : 33,
"Info_doc" : [
{
"_id" : 2,
"name" : "Johnny",
"city" : "Xingtai",
"sex" : 1
}
]
},
/* 3 */
{
"_id" : 3,
"Info_doc" : [ ---请注意为什么_id:3的数据也会联表带出来呢?下面有分析
{
"_id" : 5,
"name" : null,
"city" : "yyyy"
},
{
"_id" : 6
}
]
}
官网有句原话描述:
If an input document does not contain the
localField
, the
$lookup
treats the field as having a value of
null
for matching purposes.
If a document in the
from
collection does not contain the
foreignField
, the
$lookup
treats the value as
null
for matching purposes.
意思就是说如果无论左表,右表,只要文档中不包含连接字段,则就会假设此文档中有此字段且值为
null对待
思考:
那么又一个问题来了,我只想联表查询后显示某些字段值,不想全部都显示出来,怎么办?
答案:
使用$project,代码如下: