Update if exists, insert if it doesn’t exist – How to do Upsert in Mongoose?

To find a document and update it using Mongoose, you can use the findOneAndUpdate schema method. As the name implies, findOneAndUpdate() filter the document first that matches a given filter, applies an update, and returns the document. 

Roles.findOneAndUpdate({role:req.params.role},{modules: req.body.modules});

But what if the document that is to be updated doesn’t exist? You can insert it as a new document, right? This operation is called Upsert. Update if exists, insert if it doesn’t exist.

To use findOneAndUpdate() as as a find-and-upsert operation, set upsert as true while calling the update method.

Roles.findOneAndUpdate({role:req.params.role},{modules: req.body.modules}, {upsert: true});

By default the findOneAndUpdate() returns the document as it was before update was applied. If you want it to return the updated document, pass new=trueas third argument.

Roles.findOneAndUpdate({role:req.params.role},{modules: req.body.modules}, {new: true, upsert: true});

If you use Model.findOneAndUpdate(), by default you’ll see this warning – DeprecationWarning: Mongoose: findOneAndUpdate() and findOneAndDelete() without the useFindAndModify option set to false are deprecated. See: https://mongoosejs.com/docs/deprecations.html#-findandmodify-. This isn’t an error like this one.

To avoid this warning, please pass useFindAndModify flag as false to the mongoose connection string.

mongoose.connect(url, {poolSize: 10, bufferMaxEntries: 0, useNewUrlParser: true, useFindAndModify: false});