假设我有一系列商店:[ { "_id": 0, "items": [ {"_id": 3, "price": 10} ] }, { "_id": 1, "items": [] }, { "_id": 2 }]我想将price商店中的商品 3 更新为 30,如果该商店中没有商品,则在商店中插入一个新商品和/或在必要时插入一个新商店:商店 0:仅更新商品商店 1:附加{"_id": 3, "price": 30}到商店 1 的items商店 2:将商店 2 设置items为[{"_id": 3, "price": 30}]店铺3:插入文件{"_id": 3, "items": [{"_id": 3, "price": 30}]}换句话说,我想:collection.updateOne({_id: <shopId>, 'items._id': 3}, {$set: {'items.$.price': 30}})如果该项目存在(商店 0)collection.updateOne({_id: <shopId>}, {$push: {items: {_id: 3, price: 30}}}, {upsert: true})如果没有(商店 1 到 3)这有点像$with upsert,但文档明确指出upsert不能与它一起使用:不要将位置运算符$与 upsert 操作一起使用,因为插入将使用$作为插入文档中的字段名称。$[<identifier>]也不起作用:如果 upsert 操作不包括完全相等匹配并且没有找到匹配的文档来更新,则 upsert 操作将出错。有没有办法不用多次访问数据库就可以做到这一点?我尝试过的事情:// Updating the path 'items' would create a conflict at 'items'collection.updateOne( {_id: 0, 'items._id': 3}, {$set: {'items.$.price': 30}, $setOnInsert: {items: []}})// $[<identifier>] with upsert doesn't work// The path 'items' must exist in the document in order to apply array updates.collection.updateOne( {_id: 2}, {$set: {'items.$[item].price': 30}}, {arrayFilters: [{'item._id': 3}], upsert: true})// Updating the path 'items' would create a conflict at 'items'collection.updateOne( {_id: 0}, {$set: {'items.$[item].price': 30}, $setOnInsert: {items: []}}, {arrayFilters: [{'item._id': 3}], upsert: true})
1 回答
哆啦的时光机
TA贡献1779条经验 获得超6个赞
正如D. SM所说,您可以bulkWrite一次完成多项操作:
const shopId = 0
collection.bulkWrite([
// Remove any existing item
{
updateOne: {
filter: {_id: shopId},
update: {$pull: {items: {_id: 3}}}
}
},
// Add the item with the updated price to the shop
{
updateOne: {
filter: {_id: shopId},
update: {
$push: {items: {_id: 3, price: 30}}
},
upsert: true
}
}
])
添加回答
举报
0/150
提交
取消
