$ 带 upsert 的位置更新运算符

假设我有一系列商店:


[

  {

    "_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}

)


慕姐4208626
浏览 132回答 1
1回答

哆啦的时光机

正如D. SM所说,您可以bulkWrite一次完成多项操作:const shopId = 0collection.bulkWrite([&nbsp; // Remove any existing item&nbsp; {&nbsp; &nbsp; updateOne: {&nbsp; &nbsp; &nbsp; filter: {_id: shopId},&nbsp; &nbsp; &nbsp; update: {$pull: {items: {_id: 3}}}&nbsp; &nbsp; }&nbsp; },&nbsp; // Add the item with the updated price to the shop&nbsp; {&nbsp; &nbsp; updateOne: {&nbsp; &nbsp; &nbsp; filter: {_id: shopId},&nbsp; &nbsp; &nbsp; update: {&nbsp; &nbsp; &nbsp; &nbsp; $push: {items: {_id: 3, price: 30}}&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; upsert: true&nbsp; &nbsp; }&nbsp; }])
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript