How do I update/upsert a document in Mongoose?
Mongoose now supports this natively with findOneAndUpdate (calls MongoDB findAndModify).
The upsert = true option creates the object if it doesn't exist. defaults to false.
var query = {'username': req.user.username};req.newData.username = req.user.username;MyModel.findOneAndUpdate(query, req.newData, {upsert: true}, function(err, doc) { if (err) return res.send(500, {error: err}); return res.send('Succesfully saved.');});
In older versions Mongoose does not support these hooks with this method:
- defaults
- setters
- validators
- middleware
I just burned a solid 3 hours trying to solve the same problem. Specifically, I wanted to "replace" the entire document if it exists, or insert it otherwise. Here's the solution:
var contact = new Contact({ phone: request.phone, status: request.status});// Convert the Model instance to a simple object using Model's 'toObject' function// to prevent weirdness like infinite looping...var upsertData = contact.toObject();// Delete the _id property, otherwise Mongo will return a "Mod on _id not allowed" errordelete upsertData._id;// Do the upsert, which works like this: If no Contact document exists with // _id = contact.id, then create a new doc using upsertData.// Otherwise, update the existing doc with upsertDataContact.update({_id: contact.id}, upsertData, {upsert: true}, function(err{...});
I created an issue on the Mongoose project page requesting that info about this be added to the docs.
You were close with
Contact.update({phone:request.phone}, contact, {upsert: true}, function(err){...})
but your second parameter should be an object with a modification operator for example
Contact.update({phone:request.phone}, {$set: { phone: request.phone }}, {upsert: true}, function(err){...})