假设我有一系列商店:
[
{
"_id": 0,
"items": [
{"_id": 3, "price": 10}
]
},
{
"_id": 1,
"items": []
},
{
"_id": 2
}
]
我想将price
商店中的商品 3 更新为 30,如果该商店中不存在商品,则在商店中插入新商品和/或在必要时插入新商店:
- shop 0:简单地更新商品
- 商店 1:附加
{"_id": 3, "price": 30}
到商店 1items
- shop 2:将shop 2设置
items
为[{"_id": 3, "price": 30}]
- shop 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}
)