我最近开始使用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并且该表的状态为“ AVAILABLE”。
我的更新声明:
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' } }
);
这里的问题是我需要状态为'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' },
arrayFilters: [ { "table._id": ObjectId("5ee277bab0df345e54614b61"), 'table.status': 'AVAILABLE' } ]
}
);
通过这种方式,您正在更新具有tableId
和status
的表元素
希望有帮助