Traveling Tech Guy Traveling Tech Guy - 2 months ago 126x
Javascript Question

How do I update/upsert a document in Mongoose?

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' }
mongoose.model('Contact', ContactSchema); //is this line superflous??
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: ...}
    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
, how do I update it if it exists, or add it if it doesn't?

Thanks for your time.


Well, I waited long enough and no answer. Finally gave up the whole update/upsert approach and went with:

ContactSchema.findOne({phone:}, function(err, contact) {
    if(!err) {
        if(!contact) {
            contact = new ContactSchema();
        contact.status = request.status; {
            if(!err) {
                console.log("contact " + + " created at " + contact.createdAt + " updated at " + contact.updatedAt);
            else {
                console.log("Error: could not save contact " +;

Does it work? Yep. Am I happy with this? Probably not. 2 DB calls instead of one.
Hopefully a future Mongoose implementation would come up with a Model.upsert function.