Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving rails project from MySQL to MongoDB

I've got one project in development. I use mysql and ActiveRecord. It looks like this project is good one to start using MongoDB (which I've never used) with Mongoid adapter.

What is the best way to move my project to Mongo? As I understand I should edit my models (not a big deal) and that's all?

How can I export my data from Mysql database to Mongo? I've just tried yaml_db but it doesn't help me.

And second question is how should I keep safe my Mongo database if my system crashes (as I understand Mongo will loose data as far as it stores data in RAM). My db is 10%/90% write/read.

like image 572
fl00r Avatar asked Dec 21 '22 16:12

fl00r


2 Answers

I have done something similar recently and approached it as a 3 step process. There may be a more Rails way of doing this, but this way worked for me and was painless.

I used an iterative approach and took advantage of the fact that MongoDB is actually a very relational friendly document storage system. I started with a relational setup using Mongoid's Relational Associations (bottom of page) syntax of references_many and referenced_in. Once things were working I refactored iteratively into a more document oriented approach.

1. Dump the existing database straight to MongoDB

I used my existing models to brute force dump the SQL tables and data into parallel MongoDB documents. I just slammed everything I had into them without worrying about naming or relationships; a strict 1:1 mapping of tables to collections.

This was a one time process for me. Once everything is here steps 2 and 3 takes this data and transforms it into the structure that I wanted. I could also change my models as I no longer needed to interact with the relational system. You may want to create some sort of copy of the existing models in case you need to go back to this step for any reason.

2. Migrate the data

For the next step I went with a custom ruby shell app. Again there may be a better way to do this with Rails features, but I went with a straight forward transaction script style approach.

I used the raw MongoDB Ruby driver, read the database created in step 1, and transformed the source collections into the shapes that I wanted. I used a separate database for the destination from the one created in step 1 because I iteratively modified this script to become more and more document oriented as I refactored my model in step 3.

3. Refactor models as needed

I refactored my model to run against the database created in step 2, made my tests pass, and then went back to the script in step 2 and made changes to make the database more document oriented.

I iterated over steps 2 and 3 until I had refactored my model and document layouts until I had a final result.

like image 126
blu Avatar answered Dec 24 '22 04:12

blu


Re: your second question

1.8.0 now supports single server durability, through the addition of journaling (see docs here). That states, when you use journaling, mongo will issue batch commits every 100ms (will be more frequent in future versions). Once it's in the journal, if it crashes, it can then come back up and recover. You can request that a call into Mongo does not return until it's committed safely (at the expensive of a slight performance hit), or if using replica sets you can state how many nodes a change should be replicated to before returning - so you can make sure it's been replicated to a majority/all of the nodes.

like image 32
AdaTheDev Avatar answered Dec 24 '22 05:12

AdaTheDev