简体   繁体   中英

Mongoose Update By Passing In Array of Documents

Would functionality similar to this be possible:

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

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

Which would be similar to:

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

I am trying to avoid calling the server multiple times and I know there is a bulkWrite option and I could do something like this:

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

But this feels inefficient since it seems like it will need to load each custom query, although I am not knowledgeable on bulkWrite under the hood. I just wanted to ask if bulkWrite is only option here.

EDIT : I know the first query above will not work, but it is to show what functionality I am looking for - pass in updated objects into Mongoose and for those objects to be matched to their respective documents and updated.

The query you are using

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

It won't work because when you use the updateMany() Function, the 1st parameter is filter, which you used perfectly, But , the second one is update which you didn't use the right way.

In order to use update, you have to use one of these:

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

Or, you can simply use, updateMany({filter},{itemsids:passedIds})

As of writing, bulk write is only way of dynamically updating multiple documents at once in Mongoose (unique update for each document within one query). A complex Mongo aggregate could also accomplish updating each document differently in one query, but its performance would suffer per filter or conditional check you add in the aggregate.

I found performance of bulk write to be better than multiple Mongoose updates:

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

 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM