我有一个customers
集合,例如;
{
"_id" : ObjectId("5de8c07dc035532b489b2e23"),
"name" : "sam",
"orders" : [{"ordername" : "cola"},{"ordername" : "cheesecake"}]
}
还有waiters
集合,例如;
{
"_id" : ObjectId("5de8bc24c035532b489b2e20"),
"waiter" : "jack",
"products" : [{"name" : "cola", "price" : "4"},
{"name" : "water", "price" : "2"},
{"name" : "coffee", "price" : "8" }]
}
{
"_id" : ObjectId("5de8bdc7c035532b489b2e21"),
"waiter" : "susan",
"products" : [{"name" : "cheesecake", "price" : "12" },
{"name" : "apple pie", "price" : "14" }]
}
我想通过匹配“ products.name”和“ orders.ordername”将waiters
集合中的对象加入customers
集合中。但是,结果包括waiters
集合中的整个文档,但是,我只想要文档中匹配的对象。这就是我想要的;
ordered:[
{"name" : "cola", "price" : "4"},
{"name" : "cheesecake", "price" : "12" },
]
我尝试了$lookup
有无管道,并进行了过滤,但无法获得此结果。预先感谢。
答案 0 :(得分:1)
您有一个正确的想法,由于结构类似,我们只需要稍微“整理”数据即可。
db.collection.aggregate([
{
$addFields: {
"orderNames":
{
$reduce: {
input: "$orders",
initialValue: [],
in: {$concatArrays: [["$$this.ordername"], "$$value"]}
}
}
}
},
{
$lookup:
{
from: "waiters",
let: {orders: "$orderNames"},
pipeline: [
{
$unwind: "$products"
},
{
$match:
{
$expr:{$in: ["$products.name", "$$orders"]},
}
},
{
$group: {
_id: "$products.name",
price: {$first: "$products.price"}
}
},
{
$project: {
_id: 0,
price: 1,
name: "$_id"
}
}
],
as: "ordered"
}
}
])