Mongoose Changing Schema Format


Question

We're rapidly developing an application that's using Mongoose, and our schema's are changing often. I can't seem to figure out the proper way to update a schema for existing documents, without blowing them away and completely re-recreating them from scratch.

I came across http://mongoosejs.com/docs/api.html#schema_Schema-add, which looks to be right. There's little to no documentation on how to actually implement this, making it very hard for someone who is new to MongoDB.

I simply want to add a new field called enabled. My schema definition is:

var sweepstakesSchema = new Schema({
    client_id: {
        type: Schema.Types.ObjectId,
        ref: 'Client',
        index: true
    },
    name: {
        type: String,
        default: 'Sweepstakes',
    },
    design: {
        images: {
            type: [],
            default: []
        },
        elements: {
            type: [],
            default: []
        }
    },
    enabled: {
        type: Boolean,
        default: false
    },
    schedule: {
        start: {
            type: Date, 
            default: Date.now
        },
        end: {
            type: Date,
            default: Date.now
        }
    },
    submissions: {
        type: Number,
        default: 0
    }
});
1
24
1/11/2013 10:19:27 PM

Accepted Answer

There's nothing built into Mongoose regarding migrating existing documents to comply with a schema change. You need to do that in your own code, as needed. In a case like the new enabled field, it's probably cleanest to write your code so that it treats a missing enabled field as if it was set to false so you don't have to touch the existing docs.

As far as the schema change itself, you just update your Schema definition as you've shown, but changes like new fields with default values will only affect new documents going forward.

13
1/11/2013 11:23:38 PM

  db.sweepstakesModel.find( { enabled : { $exists : false } } ).forEach(
   function (doc) {
       doc.enabled = false;
       db.sweepstakesModel.save(doc);
    }
  )

considering your mongoose model name as "sweepstakesModel", This code would add "enabled" field with boolean value "false" to all the pre-existing documents in your collection.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon