首页 > 解决方案 > MongoDB 更新数组中错误的子文档

问题描述

我最近开始使用 Mongoose(来自 NodeJS)使用 MongoDB,但现在我在更新数组中的子文档时遇到了困难。我来给你展示...

我在 MongoDB 中设置了我的餐厅,如下所示:

_id: ObjectId("5edaaed8d8609c2c47fd6582")
name: "Some name"
tables: Array
  0: Object
    id: ObjectId("5ee277bab0df345e54614b60")
    status: "AVAILABLE"
  1: Object
    id: ObjectId("5ee277bab0df345e54614b61")
    status: "AVAILABLE"

正如你所看到的,一家餐厅显然可以有多张桌子。现在我想更新我知道_id 的表的状态。我也知道有桌子的餐厅的_id。但是....如果我们有相应的 tableId 并且该表的状态为“可用”,我只想更新状态。

我的更新声明:

const result = await Restaurant.updateOne(
  {
    _id: ObjectId("5edaaed8d8609c2c47fd6582"), 
    'tables._id': ObjectId("5ee277bab0df345e54614b61"), 
    'tables.status': 'AVAILABLE' 
  },
  { $set: { 'tables.$.status': 'CONFIRMED' } }
);

猜猜当我运行上面的更新语句时会发生什么?它奇怪地更新了 FIRST 表(使用错误的 table._id)!但是,当我从查询中删除“tables.status”过滤器时,它会更新正确的表:

const result = await Restaurant.updateOne(
  {
    _id: ObjectId("5edaaed8d8609c2c47fd6582"), 
    'tables._id': ObjectId("5ee277bab0df345e54614b61")
  },
  { $set: { 'tables.$.status': 'CONFIRMED' } }
);

这里的问题是我需要状态为“可用”,否则它不应该更新!任何人都可以指出我的正确方向吗?

标签: mongodbmongoosemongodb-querymongoose-schema

解决方案


根据文档,位置 $ 运算符充当与查询文档匹配的第一个元素的占位符

所以您只更新文档中与您的查询匹配的第一个数组元素

您应该使用过滤的位置运算符 $[identifier]

所以你的查询将是这样的

const result = await Restaurant.updateOne(
  {
    _id: ObjectId("5edaaed8d8609c2c47fd6582"),
    'tables._id': ObjectId("5ee277bab0df345e54614b61"),
    'tables.status': 'AVAILABLE'
  },
  {
    $set: { 'tables.$[table].status': 'CONFIRMED' } // update part
  },
  { 
    arrayFilters: [{ "table._id": ObjectId("5ee277bab0df345e54614b61"), 'table.status': 'AVAILABLE' }] // options part
  }
);

通过这种方式,您正在更新具有该元素的表格元素,tableId并且status

希望能帮助到你


推荐阅读