Mongodb 更新管道更新嵌套数组中元素的字段

标签 mongodb aggregation-framework mongodb-nodejs-driver

我有一个包含此类对象的集合。

{
  materials: {
    "m1": {
      inventory: [
        {
          price: 100,
          amount: 65
        }
      ]
    }
  }
}
如您所见,库存是层次结构深处的一个数组。我要更新amount它的领域。
我从客户端收到 Material ID ( "m1" ) 和库存索引 ( 0 )。
我必须使用更新管道,因为我正在设置和取消设置本文档中的其他一些字段。
这是我尝试过的:
await products.findOneAndUpdate(filters, [
  {
    $set: {
      "materials.m1.inventory.0.amount": 100,
    },
  },
]);
但是它在第 0 个元素内创建了一个名为 0 的新字段并设置了 amount在那个对象里面。所以生成的文档看起来像这样。
{
  materials: {
    "m1": {
      inventory: [
        {
          0: {
            amount: 100
          }
          price: 100,
          amount: 65
        }
      ]
    }
  }
}
而我想要的是:
{
  materials: {
    "m1": {
      inventory: [
        {
          price: 100,
          amount: 100
        }
      ]
    }
  }
}
我确定要更新数组中的哪个元素的唯一方法是它的索引。
我正在使用 nodejs mongodb 驱动程序。怎么写$set此更新管道的阶段?

最佳答案

我认为没有任何其他方法可以使用聚合管道更新特定索引位置元素,

  • $range生成从 0 到 materials.m1.inventory 长度的数组阵列
  • $map迭代上述范围数组的循环
  • $cond检查当前元素是否为 0 然后去更新部分否则从 materials.m1.inventory 返回元素按输入索引
  • $arrayElemAtmaterials.m1.inventory 获取特定元素
  • $mergeObjects将当前对象与 amount 合并更新属性
  • await products.findOneAndUpdate(filters, [
      {
        $set: {
          "materials.m1.inventory": {
            $map: {
              input: {
                $range: [0, { $size: "$materials.m1.inventory" }]
              },
              in: {
                $cond: [
                  { $eq: ["$$this", 0] }, // 0 position
                  {
                    $mergeObjects: [
                      { $arrayElemAt: ["$materials.m1.inventory", "$$this"] },
                      { amount: 100 } // input amount
                    ]
                  },
                  { $arrayElemAt: ["$materials.m1.inventory", "$$this"] }
                ]
              }
            }
          }
        }
      }
    ]);
    
    Playground

    关于Mongodb 更新管道更新嵌套数组中元素的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68888675/

    相关文章:

    node.js - 没有使用 mongoose 6 定义的 DEFAULT 的 AuthProvider

    node.js - 如何仅获取虚拟属性。 Node.JS + Mongoose + MongoDB

    node.js - 使用 Node 连接到 MongoDB 服务器在本地主机上没有响应

    mongodb - 按值排序项目 mongodb

    Python 按日期范围求和值

    mongoDB 有没有办法让聚合 $gte 不显示错误数据

    javascript - Meteor 出版物和订阅

    node.js - 如果文件未导出,如何使用在单独文件中定义的 Mongoose 模型?

    javascript - 在 MongoDB 文档中移动元素