Search code examples
node.jsmongodbmongooseslug

How to migrate existing objects when adding url slug identifier to mongoose schemas


I'm currently using Mongodb ObjectIds in my urls but I would like to use this module instead: https://github.com/dylang/shortid

But none of the existing data will have these slugs yet. How can I migrate them all? Everywhere I look people are saying you don't need to migrate data in noSQL.

Here's an example schema, I'm adding the 'shortid' field:

var ItemSchema = new Schema({
    name    : { type: String, required: true, trim: true }
    , description: { type: String, trim: true }
    , comments  : [CommentSchema]
    , shortid : { type: String, required: true }
});

My intention is to use urls like /items/PPBqWA9 instead of /items/508cbd80c0e1a44277000003

I will have a .pre('save') method that generates the shortid if it doesn't exist already.

Or maybe I can have the default be a function that calls ShortId.generate()?

Two requirements: 1) Never change it 2) Apply to existing objects retro-actively.


Solution

  • I think your choices are either: have your code deal with the fact that the index can be in transition for a potentially extended period of time, or update everything at once and then do a single code change.

    The latter seems less messy, but requires that you be able to batch process all of your item documents. In that case you could:

    1. Add a unique index to your schema with a default as you suggested. Using schema.pre seems unnecessary since ShortId.generate is not an asynchronous function call. Something like shortid: { type: String, default: ShortId.generate(), required: true, index: {unique: true}}

    2. Write a script to load all existing items, and save them with the new shortid property.

    3. Adjust the rest of your code to start using shortid rather than the id.