Dealing with schema changes in Mongoose

Update: Tested, this does not work in its current form, its got the right idea going, I got a single migration to work with considerable tweaking of the module itself. But I don't see it working as intended without some major changes and keeping track of the different schemas somehow.


Sounds like you want mongoose-data-migrations

It is intended to migrate old schema versions of your documents as you use them, which is seems to be the best way to handle migrations in mongodb.

You don't really want to run full dataset migrations on a document collection (ala alter table) as it puts a heavy load on your servers and could require application / server downtime. Sometimes you may need to write a script which simply grabs all documents applies the new schema / alterations and calls save, but you need to understand when/where to do that. An example might be, adding migration logic to doc init has more of a performance hit than taking down the server for 3 hours to run migration scripts is worth.

I found this link pretty helpful as well, basically reiterates the above in more detail and essentially implements the above node package's concept in php.

N.B. The module is 5months old, 0 forks, but am looking around and can't find anything better / more helpful than abdelsaid's style of response..


It's funny though, MongoDB was born to respond to the schema problems in RDBMS. You don't have to migrate anything, all you have to do is set the default value in the schema definition if the field is required.

new Schema({
    name: { type: string }
})

to:

new Schema({
    name: { type: string },
    birthplace: { type: string, required: true, default: 'neverborn' }
});

I just had this problem where I needed to update my database to reflect the changes to my schema. After some research I decided to try the updateMany() function in the mongo console to make the updates and I think it worked pretty well.

To apply this to vimdude's example the code would look as follows:

try { 
    db.<collection>.updateMany( { birthplace: null }, { $set: 
              {"birthplace": "neverborn" } } ); 
} catch(e) { 
    print(e);
}

The updateMany() function will update all documents in a collection based on a filter. In this case the filter is looking for all documents where the field 'birthplace' is null. It then sets a new field in those documents named 'birthplace' and sets its value to 'neverborn'.

After running the code, modified to reflect your circumstances run:

db.<collection>.find().pretty()

to verify that the changes were made. The new field "birthplace" with the value of "neverborn" should show at the end of each document in your collection.

Hope that helps.