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

MongoDB聚合:从嵌套数组生成warehouseStatus新字段

MongoDB聚合:为每个instock元素添加warehouseStatus字段

假设集合文档结构示例

{
  "_id": ObjectId("60d21b4667d0d8992e610c85"),
  "product": "notebook",
  "instock": [
    {
      "sku": "NB-001",
      "warehouse": [
        { "status": "in_stock", "createdAt": ISODate("2024-01-01T00:00:00Z") },
        { "status": "out_of_stock", "createdAt": ISODate("2024-01-05T00:00:00Z") }
      ]
    },
    {
      "sku": "NB-002",
      "warehouse": [
        { "status": "backordered", "createdAt": ISODate("2024-01-02T00:00:00Z") },
        { "status": "in_stock", "createdAt": ISODate("2024-01-06T00:00:00Z") }
      ]
    }
  ]
}

适用MongoDB 5.2+的聚合方案

利用$sortArray直接对数组排序并取最新元素,效率更高:

db.inventory.aggregate([
  // 拆分instock数组,逐个处理每个元素
  { $unwind: "$instock" },
  // 给每个instock添加临时字段,存储排序后的最新warehouse记录
  {
    $addFields: {
      "instock.latestWarehouse": {
        $first: {
          $sortArray: {
            input: "$instock.warehouse",
            sortBy: { createdAt: -1 } // 按createdAt降序,最新的排在最前
          }
        }
      }
    }
  },
  // 提取最新warehouse的status作为warehouseStatus
  {
    $addFields: {
      "instock.warehouseStatus": "$instock.latestWarehouse.status"
    }
  },
  // 清理临时字段
  { $unset: "instock.latestWarehouse" },
  // 将拆分后的instock元素重新组合为数组,同时保留原文档其他顶级字段
  {
    $group: {
      _id: "$_id",
      instock: { $push: "$instock" },
      product: { $first: "$product" } // 替换为你实际需要保留的顶级字段
    }
  }
])

兼容低版本MongoDB(<5.2)的聚合方案

如果你的MongoDB版本不支持$sortArray,可以用以下方式实现:

db.inventory.aggregate([
  // 拆分instock数组
  { $unwind: "$instock" },
  // 拆分每个instock下的warehouse数组
  { $unwind: "$instock.warehouse" },
  // 按文档ID、instock元素、createdAt降序排序,确保最新的warehouse排在最前
  {
    $sort: {
      "_id": 1,
      "instock.sku": 1, // 用instock的唯一标识字段排序,比如sku
      "instock.warehouse.createdAt": -1
    }
  },
  // 按文档ID和instock唯一标识分组,取第一个(最新的)warehouse的status
  {
    $group: {
      _id: {
        docId: "$_id",
        sku: "$instock.sku"
      },
      instock: { $first: "$instock" },
      latestStatus: { $first: "$instock.warehouse.status" },
      product: { $first: "$product" } // 保留原文档顶级字段
    }
  },
  // 添加warehouseStatus字段
  {
    $addFields: {
      "instock.warehouseStatus": "$latestStatus"
    }
  },
  // 清理临时字段
  { $unset: "latestStatus" },
  // 重新组合instock数组
  {
    $group: {
      _id: "$_id.docId",
      instock: { $push: "$instock" },
      product: { $first: "$product" }
    }
  }
])

关键说明

  • 如果你需要保留原文档的其他顶级字段(如示例中的product),必须在$group阶段用$first明确指定,否则这些字段会丢失。
  • 低版本方案中,需要用instock元素的唯一标识(如sku)来分组,确保每个instock元素能正确匹配到最新的warehouse状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 17:31:12