Explore Courses Blog Tutorials Interview Questions
0 votes
in Web Technology by (47.6k points)

Perhaps it's the time, perhaps it's me drowning in sparse documentation and not being able to wrap my head around the concept of updating in Mongoose :)

Here's the deal:

I have a contact schema and model (shortened properties):

var mongoose = require('mongoose'), 

Schema = mongoose.Schema; 

var mongooseTypes = require("mongoose-types"),

useTimestamps = mongooseTypes.useTimestamps; 

var ContactSchema = new Schema({ 

phone: { 

type: String, 

index: { 

unique: true, 

dropDups: true 


status: { 

type: String, 

lowercase: true, 

trim: true, 

default: 'on' 



var Contact = mongoose.model('Contact', ContactSchema);

I receive a request from the client, containing the fields I need and use my model thusly:


var contact = new Contact({ 


status: request.status 


And now we reach the problem:

  1. If I call{...}) I'll receive an error if the contact with the same phone number already exists (as expected - unique)

  2. I can't call update() on contact since that method does not exist on a document

  3. If I call update on the model:
    Contact.update({}, contact, {upsert: true}, function(err{...})
    I get into an infinite loop of some sorts since the Mongoose update implementation clearly doesn't want an object as the second parameter.

  4. If I do the same, but in the second parameter I pass an associative array of the request properties {status: request.status, phone: request. phone ...} it works - but then I have no reference to the specific contact and cannot find out its createdAt and updatedAt properties.

So the bottom line, after all, I tried: given a document contact, how do I update it if it exists, or add it if it doesn't?

Thanks for your time.

2 Answers

0 votes
by (106k points)

To update/upsert a document inside MongoDB you can use the below-mentioned method, 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"); 


0 votes
by (50.2k points)

Now Mongoose uses findOneAndUpdate() that finds the first document that matches a given filter and then applies an update and returns the document. By default, findOneAndUpdate() returns the document as it was before the update was applied. After using the upsert option, you can use findOneAndUpdate() as a find-and-upsert method. An upsert acts like a normal findOneAndUpdate() if it finds a document that matches the filter. But, if no document matches the filter, MongoDB will insert one by combining filter and update.

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.');


Related questions

0 votes
2 answers
0 votes
1 answer
0 votes
2 answers
0 votes
1 answer

Browse Categories