Migration needed to change the type of a property inside the Schema of a meteor collection?

70 Views Asked by At

I have a Simpleschema of a Meteor Collection like this:

Users.attachSchema(new SimpleSchema({: {
  ...
  age: {
   type: String,
   optional: true
  },
  ...
}));

Now i want to change age's type to type: Number.

Q1: Do i have to run a migration?
Q2: If so, how would the migration look like?

1

There are 1 best solutions below

2
Jankapunkt On

Usually these kinds of question are really broad but I just try to give you some idea on how to think about this issue:

Q1: Do i have to run a migration?

If you have external models, controllers or views which depend on or make use of age (even implicitly) and expect it to be a number, then you need to migrate.

Q2: If so, how would the migration look like?

There are many options here.

For instance you can do a fast migration and just change the schema to use Number and update any code that uses age to handle it as a Number. To ensure compatibility you would require to write a patch, that updates all existing documents with age being a String to Number.

You can also do a much slower migration and keep your model backwards compatible by extending your schema:

Users.attachSchema(new SimpleSchema({: {
  ...
  age: {
    type: String,
    optional: true
  },
  ageNum: {
    type: Number,
    optional: true
  }
  ...
}));

Then you write a helper, that always returns the age in the new format, with fallback to the old structure:

const getAge = userDoc => {
  if (!userDoc) return

  // compatibility to schema v.2
  if (typeof user.ageNum === 'number') {
    return user.ageNum
  }

  // fallback compatibility to schema v.1
  if (typeof user.age === 'string') {
    return parseInt(user.age, 10)
  }

  // else do nothing, which returns undefined
  // when age and ageNum are not set
}

Then you rewrite the other code to use only getAge to retrieve the age. Note, that you also need to update methods, that insert / update user documents, so they use ageNum instead of age.

Using this approach all new users will have a Number based age by default, while older documents, that have not been updated yet are still supported. This avoids the need to patch all documents for integrity.

There are many other options here and it is hard to give a more precise answer.