Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with schema changes in Mongoose

What's the best practice (or tool) for updating/migrating Mongoose schemas as the application evolves?

like image 237
mahemoff Avatar asked Sep 30 '11 23:09

mahemoff


People also ask

Can Mongoose schema be changed?

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.

Can we change schema in MongoDB?

Collections in MongoDB do not have a fixed schema, or requirement for all documents in a collection to have the same schema. You can definitely add or remove fields, change field types, or update JSON Schema validation without recreating a collection.

What does $Set do in Mongoose?

The $set operator replaces the value of a field with the specified value.

Does Mongoose need schema?

Everything in Mongoose starts with a Schema. Each schema maps to a MongoDB collection and defines the shape of the documents within that collection.

Is it possible to do a schema change in MongoDB?

We don't really have to do a schema change, but we do need to update each document. MongoDB however does not allow you to update fields according to the value of other fields so we can not simply do a: Although you can retrieve the data like this through the Aggregation Framework: Note that I am abusing $concat here.

What is migrations in MongoDB used for?

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.

Do I have to migrate a field from one schema to another?

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. Show activity on this post. I just had this problem where I needed to update my database to reflect the changes to my schema.

Is there a way to use string functions in MongoDB?

A user actually suggested you use map reduce in MongoDB which would then allow you to use the java-script library of string functions. Harness technology creatively for a wondrous outcome. Good question. For your information, MongoDB stores documents in schema-less collections.


3 Answers

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' } }); 
like image 161
vimdude Avatar answered Sep 18 '22 12:09

vimdude


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..

like image 20
Louis Avatar answered Sep 20 '22 12:09

Louis


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.

like image 25
Aaron Pennington Avatar answered Sep 20 '22 12:09

Aaron Pennington