You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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
    }
  }
])

各步骤说明

  1. $graphLookup:和原逻辑一致,递归遍历盒子的嵌套关系,把容器下所有层级的盒子存入allBoxes数组。
  2. 合并物品ID数组:用$reduce+$concatArrays把每个盒子的items数组合并成一个一维数组,解决二维数组无法直接关联的问题。
  3. 去重ID:用$setUnion去除重复的物品ID,避免同一个物品被多个盒子引用时重复出现在结果里。
  4. 关联物品集合:通过$lookup根据ID数组从items集合取出对应的物品详情。
  5. 精简输出:可选步骤,只保留容器ID和最终结果字段,让输出更简洁。

示例数据验证结果

  • 容器_id:1的result会包含物品1、2、3、4、5、6
  • 容器_id:2的result会包含物品8
  • 容器_id:3的result为空数组

内容的提问来源于stack exchange,提问作者Gandalf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 06:36:08