如何使用graphLookup获取容器内嵌套盒子中的所有物品?
修正MongoDB查询以获取容器内所有嵌套盒子的物品
原查询的第二个$graphLookup用错了——items集合里并没有items字段,而且物品是直接存放在盒子的items数组里,不需要递归查找。另外$allBoxes.items是一个二维数组(每个盒子对应一个items数组),直接传给startWith也不符合$graphLookup的输入要求,这就是返回空数组的原因。
以下是修正后的聚合查询:
db.containers.aggregate([ // 递归获取容器下所有直接/间接嵌套的盒子 { $graphLookup: { from: "boxes", startWith: "$boxes", connectFromField: "boxes", connectToField: "_id", as: "allBoxes" } }, // 合并所有盒子的items数组为一维数组 { $addFields: { allItemIds: { $reduce: { input: "$allBoxes.items", initialValue: [], in: { $concatArrays: ["$$value", "$$this"] } } } } }, // 对物品ID去重(避免重复引用) { $addFields: { uniqueItemIds: { $setUnion: ["$allItemIds"] } } }, // 关联items集合获取物品详情 { $lookup: { from: "items", localField: "uniqueItemIds", foreignField: "_id", as: "result" } }, // 可选:精简输出字段 { $project: { _id: 1, result: 1 } } ])
各步骤说明
$graphLookup:和原逻辑一致,递归遍历盒子的嵌套关系,把容器下所有层级的盒子存入allBoxes数组。- 合并物品ID数组:用
$reduce+$concatArrays把每个盒子的items数组合并成一个一维数组,解决二维数组无法直接关联的问题。 - 去重ID:用
$setUnion去除重复的物品ID,避免同一个物品被多个盒子引用时重复出现在结果里。 - 关联物品集合:通过
$lookup根据ID数组从items集合取出对应的物品详情。 - 精简输出:可选步骤,只保留容器ID和最终结果字段,让输出更简洁。
示例数据验证结果
- 容器
_id:1的result会包含物品1、2、3、4、5、6 - 容器
_id:2的result会包含物品8 - 容器
_id:3的result为空数组
内容的提问来源于stack exchange,提问作者Gandalf
相关产品推荐
相关产品推荐

