Gre*_*mas 4 mongodb nosql nosql-aggregation aggregation-framework
假设 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"
}
]
Run Code Online (Sandbox Code Playgroud)
[
{
order_id: 1,
customer_id: 1
},
{
order_id: 2,
customer_id: 1
}
]
Run Code Online (Sandbox Code Playgroud)
[
{
order_item_id: 1,
name: "Foo",
price: 4.99,
order_id: 1
},
{
order_item_id: 2,
name: "Bar",
price: 17.99,
order_id: 1
},
{
order_item_id: 3,
name: "baz",
price: 24.99,
order_id: 2
}
]
Run Code Online (Sandbox Code Playgroud)
如何编写聚合管道以使返回的结果看起来像这样?
[
{
customer_id: 1,
name: "Jim Smith",
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
}
]
}
]
},
{
customer_id: 2,
name: "Bob Jones",
email: "bob.jones@example.com"
orders: []
}
]
Run Code Online (Sandbox Code Playgroud)
使用带管道的查找进行嵌套查找,
$lookup与orders收藏,
let,定义customer_id来自主集合的变量,以使用$$like访问管道内的此引用变量$$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"
}
}
])
Run Code Online (Sandbox Code Playgroud)
提示:
在NoSQL中,有几种连接被认为是不好的做法,我建议您是否可以将订单项添加到订单集合中作为数组,您可以为订单项保存一个连接过程,请参阅playground中的改进版本