Mongoose 通过传入文档数组进行更新

Mongoose Update By Passing In Array of Documents

是否可以实现与此类似的功能:

let Item = mongoose.model('Item')
let updatedItems = [updatedItem1, updatedItem2]
let updatedItemIds = [updatedItem1._id, updatedItem2._id]

Item.updateMany({_id: {$in: updatedItemIds }}, updatedItems) // this wont work

类似于:

updatedItems.forEach( item => {
    Item.updateOne({_id: item._id}, item) 
})

我试图避免多次调用服务器,我知道有一个 bulkWrite 选项,我可以这样做:

bulk = []
updatedItems.forEach( item => { 
  let updateDoc = {
    'updateOne': {
      'filter': { '_id': item._id },
      'update': item,
      'upsert': false
     }
  }  
  bulk.push(updateDoc)
})
Item.collection.bulkWrite(bulk)

但这感觉效率低下,因为它似乎需要加载每个自定义查询,尽管我不了解 bulkWrite 的底层知识。我只是想问一下这里是否只有 bulkWrite 选项。

编辑: 我知道上面的第一个查询不起作用,但它是为了显示我正在寻找的功能 - 将更新的对象传递到 Mongoose 中,并让这些对象与各自的文档匹配并更新。

您正在使用的查询

Item.updateMany({_id: {$in: updatedItemIds }}, updatedItems);

它不会工作,因为当你使用updateMany()函数时,第一个参数是filter,你用得很好,但是,第二个参数是update,你没有使用正确的方法。

要使用更新,您必须使用其中之一:

  $addFields and its alias $set
    $project and its alias $unset
    $replaceRoot and its alias $replaceWith.

或者,您可以简单地使用,updateMany({filter},{itemsids:passedIds})

截至撰写本文时,批量写入是在 Mongoose 中一次动态更新多个文档的唯一方法(一次查询中每个文档的唯一更新)。一个复杂的 Mongo 聚合也可以在一个查询中完成对每个文档的不同更新,但它的性能会受到您在聚合中添加的每个过滤器或条件检查的影响。

我发现批量写入的性能优于多个 Mongoose 更新:

bulk = []
updatedItems.forEach( item => { 
  let updateDoc = {
    'updateOne': {
      'filter': { '_id': item._id },
      'update': item,
      'upsert': false
     }
  }  
  bulk.push(updateDoc)
})
Item.collection.bulkWrite(bulk)