mongodb 3.x 新功能使用$lookup做多表关联处理(十一)
  nQkVcpdWfLDr 2023年11月02日 61 0

mongodb3.2新增加了一个新功能就是$lookup,其是放到了aggreation这种重量级的pipeline分析框架上,相当于关系型数据库的关联查询。

1.介绍Aggregate

这个aggregate在mongodb中算是一个非常重量级的工具了,而且pipeline的管道模型的理论就是后面操作的数据源来源于上一次操作的结果,这个 应该很好理解吧,好了,下面我们简单看看aggreation中到底有哪几个一等公民。

mongodb 3.x 新功能使用$lookup做多表关联处理(十一)_外键

很简单,就是上面的这十三个,比如说有了所谓的group操作,我们就可以把这个aggreation做group的处理,有了sort操作,就可以将结果进行排序,有了$out操作,我们就可以将结果放到一个collections中去或者inline模式展示。

2.数据准备

说了这么多,下面我们简单的来演示一下,比如我们有一个product表,有一个orders表,自然就存在着一个外键关系,下面我们就来造点数据。  

db.product.insert({"_id":1,"productname":"商品1","price":15})
db.product.insert({"_id":2,"productname":"商品2","price":36})

db.orders.insert({"_id":1,"pid":1,"ordername":"订单1"})
db.orders.insert({"_id":2,"pid":2,"ordername":"订单2"})
db.orders.insert({"_id":3,"pid":2,"ordername":"订单3"})
db.orders.insert({"_id":4,"pid":1,"ordername":"订单4"})

db.product.find()
db.orders.find()

mongodb 3.x 新功能使用$lookup做多表关联处理(十一)_数据_02

好了,数据已经构造完毕,接下来我们要做的一个小需求就是,在orders表中,找到price of product >20 的订单,这个需求看起来很简单,对吧, 但是呢,我们的orders表中是没有price的field的。

3.$lookup 表关联  

db.product.aggregate([{
$lookup:{
from:"orders",
localField:"_id",
foreignField:"pid",
as:"inventory_docs"
}
}])

mongodb 3.x 新功能使用$lookup做多表关联处理(十一)_外键_03

下面我简单介绍一些$lookup中的参数:

from:需要关联的表【orders】

localField: 【product】表需要关联的键。

foreignField:【orders】的matching key。

as:  对应的外键集合的数据,【因为可能是一对多的,对吧】

 好了,表关联已经做好了,接下来我们就需要用另外一个关键词叫做$match,where条件的意思嘛。

4.$match筛选

查找价格大于20的数据:

db.product.aggregate([
{
$lookup:{
from:"orders",
localField:"_id",
foreignField:"pid",
as:"inventory_docs"
}
},
{
$match:{price:{$gt:20}}
}
])

mongodb 3.x 新功能使用$lookup做多表关联处理(十一)_外键_04

果然不出所料,我们就把”商品1“过滤掉了,因为它的价格小于20,对吧,但是呢,看起来还不是很完美,应为我只需要orders信息,并不想要 所谓的product 这些属性,这个时候我们就可以使用$project 做select操作了。

还有一个就是我们只想拿到关联的数据,此时可以使用$size过滤({$size:1} 表示是有关联到数据;  {$size:0}表示没有关联到数据)

以下例子中表示只查询关联到的数据:

db.product.aggregate([
{
$lookup:{
from:"orders",
localField:"_id",
foreignField:"pid",
as:"inventory_docs"
}
},
{
$match:{price:{$gt:20},"inventory_docs":{$size:1}}
}
])

还可以采用"as_docs":{ $ne: [] }过滤(表示不为空的数组)

mongodb 3.x 新功能使用$lookup做多表关联处理(十一)_数据_05

如果此时要对orders表增加过滤条件:

db.product.aggregate([
{
$lookup:{
from:"orders",
localField:"_id",
foreignField:"pid",
as:"inventory_docs"
}
},
{
$match:{price:{$gt:20},"inventory_docs.ordername":"订单5","inventory_docs":{$size:1}}
}
])

mongodb 3.x 新功能使用$lookup做多表关联处理(十一)_数据_06

5.$project 挑选字段

下来我们使用$project来指定我要获取的字段,比如我只需要inventory_docs字段就可以 :

db.product.aggregate([
{
$lookup:{
from:"orders",
localField:"_id",
foreignField:"pid",
as:"inventory_docs"
}
},
{
$match:{price:{$gt:20}}
},
{
$project:{inventory_docs:1,_id:0}
}
])

mongodb 3.x 新功能使用$lookup做多表关联处理(十一)_数据_07

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
nQkVcpdWfLDr