如何在MongoDB Pipeline Lookup中基于首次关联结果实现二次Lookup
MongoDB 实现嵌套关联生成嵌套数组
集合结构示例
- ROOT(客户集合)
{"_id":1,"type":"customer","name":"anton"}
- A(订单集合)
{"_id":33, "customer":1, "type":"order","address":"azores island"}
- B(订单项集合)
{"_id":"1_33_1", "type":"item","name":"golf ball"}
聚合查询实现
直接用嵌套的$lookup结合$map实现二次关联,最终生成包含orders和嵌套items的结构:
db.ROOT.aggregate([ // 关联订单集合A,生成orders数组 { $lookup: { from: "A", localField: "_id", foreignField: "customer", as: "orders" } }, // 为每个订单关联对应的订单项集合B { $addFields: { orders: { $map: { input: "$orders", as: "order", in: { $mergeObjects: [ "$$order", { items: { $lookup: { from: "B", let: { customerId: "$_id", orderId: "$$order._id" }, pipeline: [ { $match: { $expr: { $regexMatch: { input: "$_id", regex: { $concat: [ { $toString: "$$customerId" }, "_", { $toString: "$$orderId" }, "_" ] } } } } } ], as: "items" } } } ] } } } } } ])
逻辑说明
- 第一阶段
$lookup:将客户ID(ROOT._id)与订单集合A的customer字段匹配,把属于该客户的所有订单存入orders数组。 - 第二阶段
$addFields+$map:遍历每个订单,用$mergeObjects保留原订单的所有字段,同时新增items字段。 - 嵌套
$lookup:通过let定义当前客户ID和订单ID变量,利用$regexMatch匹配B集合中_id以${客户ID}_${订单ID}_开头的文档(因为B的_id是按customerId_orderId_itemIndex规则拼接的),匹配结果存入当前订单的items数组。
最终输出示例
{ "_id": 1, "type": "customer", "name": "anton", "orders": [ { "_id": 33, "customer": 1, "type": "order", "address": "azores island", "items": [ { "_id": "1_33_1", "type": "item", "name": "golf ball" } ] } ] }
内容的提问来源于stack exchange,提问作者Miro Krsjak
相关产品推荐
相关产品推荐

