如何解决如何在 MongoDB 聚合管道中执行嵌套的“连接”连接 3 个或更多集合? 客户订单订单项想要的结果
假设我们在 MongoDB 中有 3 个假设集合:customers
、orders
和 orderItems
。
每个客户有多个订单,每个订单有多个订单商品。
以下是这 3 个集合的一些示例数据:
客户
[
{
customer_id: 1,name: "Jim Smith",email: "jim.smith@example.com"
},{
customer_id: 2,name: "Bob Jones",email: "bob.jones@example.com"
}
]
订单
[
{
order_id: 1,customer_id: 1
},{
order_id: 2,customer_id: 1
}
]
订单项
[
{
order_item_id: 1,name: "Foo",price: 4.99,order_id: 1
},{
order_item_id: 2,name: "Bar",price: 17.99,{
order_item_id: 3,name: "baz",price: 24.99,order_id: 2
}
]
想要的结果
如何编写聚合管道,使返回的结果看起来像这样?
[
{
customer_id: 1,email: "jim.smith@example.com"
orders: [
{
order_id: 1,items: [
{
name: "Foo",price: 4.99
},{
name: "Bar",price: 17.99
}
]
},{
order_id: 2,items: [
{
name: "baz",price: 24.99
}
]
}
]
},email: "bob.jones@example.com"
orders: []
}
]
解决方法
使用 lookup with pipeline 进行嵌套查找,
-
$lookup
与orders
集合,-
let
,定义来自主集合的变量customer_id
,使用$$
(如$$customer_id
)访问管道内的这个引用变量, -
pipeline
可以像在根级管道中一样添加管道阶段 -
$expr
每当我们匹配内部字段时,它都需要表达式匹配条件,因此$$customer_id
是在let
中声明的父集合字段,$customer_id
是子集合/当前集合的字段
-
-
$lookup
与orderitems
集合
db.customers.aggregate([
{
$lookup: {
from: "orders",let: { customer_id: "$customer_id" },pipeline: [
{ $match: { $expr: { $eq: ["$$customer_id","$customer_id"] } } },{
$lookup: {
from: "orderitems",localField: "order_id",foreignField: "order_id",as: "items"
}
}
],as: "orders"
}
}
])
提示:
几种连接在 NoSQL 中被认为是不好的做法,我建议您是否可以将订单项作为数组添加到订单集合中,您可以为订单项节省一个连接过程,请参阅 playground 中的改进版本
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。