[英]$ positional update operator with upsert
假設我有一系列商店:
[
{
"_id": 0,
"items": [
{"_id": 3, "price": 10}
]
},
{
"_id": 1,
"items": []
},
{
"_id": 2
}
]
我想將商店中商品 3 的price
更新為 30,如果該商店中沒有商品,則在商店中插入新商品和/或在必要時插入新商店:
{"_id": 3, "price": 30}
附加到 shop 1 的items
items
設置為[{"_id": 3, "price": 30}]
{"_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) 這有點像$
與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}
)
正如D. SM所說,您可以使用bulkWrite
在一個 go 中執行多項操作:
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
}
}
])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.