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
}
);
通过这种方式,您正在更新具有 tableId
和 status
的 table 元素
希望对您有所帮助
我最近开始使用 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
}
);
通过这种方式,您正在更新具有 tableId
和 status
希望对您有所帮助