MongoDB 更新数组中的错误子文档

MongoDB updating the wrong subdocument in array

我最近开始使用 MongoDB 使用 Mongoose(来自 NodeJS),但现在我无法更新数组中的子文档。 让我告诉你...

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

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

如您所见,一家餐厅显然可以有多个 table。 现在我想更新我知道 _id 的 table 的状态。我也知道有 table 的餐厅的 _id。 但是....我只想更新状态,如果我们有相应的 tableId 并且这个 table 有状态 'AVAILABLE'.

我的更新声明:

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

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

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

这里的问题是我需要状态为'AVAILABLE',否则它不应该更新! 有人能用这个给我指出赖特的方向吗?

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

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

你应该使用 filtered positional operator $[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
  }
);

通过这种方式,您正在更新具有 tableIdstatus

的 table 元素

希望对您有所帮助