2

I'm a couple hours new to Meteor and Mongo, coming from a Rails background and trying to understand how migrations work - or don't maybe?

I have a server/bootstrap.js file that I use to seed some data:

// if the database is empty on server start, create some sample data.
Meteor.startup(function () {
  if (Users.find().count() === 0) {
    var userData = [
        { name: 'Cool guy' },
        { name: 'Other dude' }
    ];

    for (var i = 0; userData.length; i++) {
      var userId = Users.insert({
        name: userData[i].name
      });
    }
  }
});

It seems like every time I want to change the database, say to add a new field, I have to run meteor reset to get it to pick up the changes.

But what happens if I create records or other data through the UI that I want to keep? In Rails, working with MySQL or PostgreSQL, I'd create a migration to create new fields without blowing away the entire database.

How does this work with Meteor and Mongo? Also thinking of the case of rolling out new changes from development to production. Thanks!

-- Update: 2013/09/24 --

Apparently, the schema-less nature of Mongo reduces or eliminates the need for migrations. In my case, modifying userData to add new fields won't work after it runs initially because of the Users count check - which is why I kept running meteor reset. I'll need to rethink my approach here and study up.

That said, there are projects out there that use migrations, like Telescope: https://github.com/SachaG/Telescope/blob/master/server/migrations.js

I also found the tutorial at http://try.mongodb.org/ useful.

manafire
  • 5,984
  • 4
  • 43
  • 53

2 Answers2

1

There are no migrations in Mongo — there is no scheme! If you want to add a new field that was not there before, just do it and it will work. You can even have completely different documents in the same collection!

Items.insert({name: "keyboard", type: "input", interface: "usb"});
Items.insert({cherries: true, count: 5, unit: "buckets", taste: "awesome"});

This will just work. One of main reasons to use NoSQL (and advantages of Meteor over Rails) is that you don't have migrations to worry about.

 


 

Using mrt reset to change db model is a terrible idea. What it actually does is complete reset of db — it removes all of your data! While it's sometimes usefull in development, I bet it's not what you want in this case.

Hubert OG
  • 19,314
  • 7
  • 45
  • 73
1

First of all, your code is perfectly valid. And you know that.

mrt reset gives you a 'fresh' - empty database (as mentionned already). If you want to reset a particular collection, you can do it so : MyCollection.remove({});

But you have to understand the nature of NoSQL : there are no constraints on the data. It could be called NoREL (as in not a relational database, source : Wikipedia ).

MongoDB is also schema-less. This means that you can use any field you want in your data. This is up to you (the programmer) to enforce specific constraints if you want some. In other words, there is no logic on the mongo side. It should accept any data you throw at it, just like Hubert OG demonstrated. Your code snippet could be :

// if the database is empty on server start, create some sample data.
Meteor.startup(function () {
   if (Users.find().count() === 0) {
    var userData = [
      { name: 'Cool guy' },
      { name: 'Other dude' },
      { nickname: 'Yet another dude' }           // this line shows that mongo takes what you throw him
    ];

    for (var i = 0; userData.length; i++) {
      var userId = Users.insert({
        name: userData[i].name
      });
    }
  }
});

Source : http://www.mongodb.com/nosql

There is no need for migration there. You only have to add the logic in your application code.

Note : To import/export a database, you can have a look there : mongo import/export doc, and maybe at the db.copyDatabase(origin, destination, hostname) function.

nha
  • 17,623
  • 13
  • 87
  • 133
  • 1
    You're right in saying that mongo it's not relational. But it's not because the data is not relational that you can have any field you want in your data; It's because it's schema-less. – Dave Sep 23 '13 at 17:15
  • @Dave Thank you : your comment made me dig. I found that the reason is that schemas are dynamic. http://www.mongodb.com/nosql If you agree, I'll edit the post. – nha Sep 23 '13 at 19:49
  • Schema-less, dynamic schema, pretty much the same thing IMO. – Dave Sep 23 '13 at 20:01
  • I think you are right. I like the meaning conveyed by "dynamic" a bit more though. But it seems less used. (updated the post and upvoted you) – nha Sep 23 '13 at 20:22