Migrating from Mongo DB to Dynamo DB

Mongo is great. I'm using it in more then one project, and I love it.

Is there a real reason to switch to Dynamo db? Well, there are few:

  1. Mongo is a memory hog. This means you have to maintain pretty big instances in order to keep it fast and happy.

  2. Servers cost money. Not only the hourly fee, but maintenance as well. The lean startup couldn't probably afford these, and bigger companies might want the easy scalability that comes with Dynamo. Scaling Mongo is not hard, but it’s yet another thing to do.

  3. Serverless. Using Node JS and Serverless, allows you to run a whole infrastructure without… well… an infrastructure. This is huge as you don’t have to maintain anything.

So, how do we migrate?

  1. Indexes. While Mongo enforces record ID, Dynamo enforces at least one index, with the option of another one. Migration here is pretty easy: create the main index as string, and add a random string to it upon inserting a new record:

    function createUsersTable(callback) {
        let params = {
            TableName: TABLE_NAME,
            KeySchema: [{
                AttributeName: "user_id",
                KeyType: "HASH"
            }, ],
            AttributeDefinitions: [{
                AttributeName: "user_id",
                AttributeType: "S"
            }],
            ProvisionedThroughput: {
                "ReadCapacityUnits": 5,
                "WriteCapacityUnits": 5
            }
        }
        dynamodb.createTable(params, (err, data) => {
            callback(err, data)
        });
    }

     

  2. Dynamo is able to offer a schema of some sort. You don’t have to use it, but if you can, you can guarantee a certain consistency within the records.

  3. Dynamo requires types when storing data. But, If you’re using NodeJS, you’re in luck. AWS.DynamoDB.DocumentClient will extract these for you, resulting in an extremely similar manner to what you know and love from mongo:

    let dynamo = new AWS.DynamoDB.DocumentClient

    and inserting a record is as easy:

    function addUser(callback) {
        let params = {
            TableName: TABLE_NAME
        };
        let item = {
            user_id: rand.generate(),
            username: "Bick "+rand.generate(7),
            password: rand.generate(10),
            address: {
                home: "123 wrefwre,fwref",
                work: "wre 5whbwergwregwerg"
            }
        }
        params.Item = item;
        dynamo.put(params, callback);
    }

    Where rand is a module I've used to generate random strings (see full source link at the bottom).

  4. Running locally: Using Mongo locally is easy. it’s open source, and you can just install it. Dynamo DB is proprietary software, and you can’t get a copy of it. Amazon solved it by creating a Java version of the api backed by sqlite. You can now run a front of Dynamo db if you need to test your code. The only setup you need to do is the aws config:

    const credentials = {
        accessKeyId: "fakeAccessKey",
        secretAccessKey: "fakeSecretAccessKey",
        region: "fakeRegion",
        endpoint: "http://localhost:15000"
    };

     

For the local version of Dynamo db installing instructions: https://github.com/talreg/dynamodb-node/blob/master/README.md

The full sample project can be found here: https://github.com/talreg/dynamodb-node

 

Static constructor in NodeJS objects

It's not hard to create an object in JavaScript and therefore in NodeJS. However, if you're an advanced user, you probably devil a little with static objects (Factories will be the definite example). Since JavaScript doesn't really comes with static constructors, we need to take advantage of NodeJS require feature.

About require

require is a nodejs specific. The cool thing about it, is that it is only called once. so, every code that executed there, is executed only once, what's making it a perfect place for static initialization.  Lets take a look at some code:

function Counter()
{
this.counter=0;
Counter.__counters++;
}

What we have here is a simple increase of the number of objects created. However, since Counter.__counters is not defined, we will get an error. sure, we can check that this variable exists in the object constructor, and currently this is not a big issue, but if the test is a timely manner or a costly one, we have a problem. Using NodeJS feature, we can solve it easily:


Counter.__counters=0;

function Counter() 
{ 
this.counter=0;
Counter.__counters++; 
}

The first line will be called only once, and thus make it a static constructor. This line can be replace in a function call, if we wish to make it neater, and the effect will remain the same.

Some jQuery code worth knowing

using jQuery with select boxes

 

Getting the number of elements:

jQuery("#select_id").children().size()

 

getting the value (not the option text) from multiple select box option

jQuery("#select_id").children().each(
        function(i)
        {
           s1+=jQuery(this).val();
        }
        );

Removing selected items from a multiple select box:

 jQuery("#select_id"+" :selected").each(
        function(i,selected)
        {        
            jQuery(selected).remove();
        //alert("removing "+);
        });

 

Hide a select box under internet explorer

Sometimes you need to hide a select tag.

in HTML, the usual solution is

 <select name ="myname" id="myid" 
                multiple="multiple" hidden>

However, this will (obviously) will not work under MSIE even on the current version which is 9.

in order to bypass this MS bug, a css solution (open a separate css file) must be used:

.hide
{
    display:  none;
}

and then:

 <select name ="myname" id="myid" 
                multiple="multiple" hidden class="hide">

This will work on explorer 6 and above. note that if you need to un – hide this, you have to take care of the class as well.

MS, what can you do…