NodeJs Interact with MongoDB Fast and Dirty

In this blog we will see how to interact with mongodb through nodejs. We will use the mongoose library for this

I will be using this library http://mongoosejs.com/ to intract with mongodb. I assume that you already know the basics of mongodb and have installed it.

Basic Setup

In mongoose you need first create a schema for your table in your code and then create a model from the scheme. But i will just the fast and easy to do it.

Lets assume the name of our database is “blog” and table is “post”

var mongoose = require('mongoose');
var conn = mongoose.createConnection('mongodb://127.0.0.1/blog');
var post_schema = mongoose.Schema({}, {
    strict: false,
    collection: 'post'
});
var post = conn.model('post', post_schema);

Above we have create a basic model to run our queries on mongodb. The scheme is empty and we have set strict: false, so this allows us to skip the schema definition.

Basic CRUD Operations

Continuing from the above, lets Read and Insert Operation First


var mongoose = require('mongoose');
var conn = mongoose.createConnection('mongodb://127.0.0.1/blog');
var post_schema = mongoose.Schema({}, {
    strict: false,
    collection: 'post'
});
var post = conn.model('post', post_schema);

//Read from database, supports all mongo where conditions
post.find({
    title: /Test/i
}, function (err, result) {
    if (err) {
        console.log(err);
        process.exit();
    }

    if (!result || result.length == 0) {
        var new_post = new post({
            title: 'Test Title',
            cat_id: 1,
            date: new Date() + ""
        });
        new_post.save(function (err) {
            //save done
            if (err) {
                console.log(err);
                process.exit();
            }
            console.log('Post Saved')
        });
    } else {

        for (var i = 0; i < result.length; i++) {
            var row = result[i];
            var id = row.get('_id');
            var title = row.get('title');
            var cat_id = row.get('cat_id');
            console.log('Title: ' + title + 'in category: ' + cat_id + ' with _id: ' + id);
        }

    }
});

Now let us see how to Update

var mongoose = require('mongoose');
var conn = mongoose.createConnection('mongodb://127.0.0.1/blog');
var post_schema = mongoose.Schema({}, {
    strict: false,
    collection: 'post'
});
var post = conn.model('post', post_schema);

var objectID = new mongoose.Types.ObjectId('54549d4b2db33af6045d4ec1');
post.find({
    "_id": objectID
}, function(err, docs) {
    if (!err) {
        if (docs.length > 0) {
            var row = docs[0];
            post.update({
                '_id': row.get('_id')
            }, {
                $set: {
                    title: 'Updated Title'
                }
            }, function(err) {
                if (!err) {
                    console.log('Update Done');
                }
            });
        }
        else {
            console.log('Not Found');
        }
    }
});

In the above code I have also used “mongoose.Types.ObjectId” which is used for ‘_id’ in mongodb. You can see above how it can be used in find() and how to get(‘_id’) it.

To delete a row, we can simply use the remove() function just like save() and find().

Insert Multiple Rows Together And Callback when done

We will see a very common case, suppose we have an array of records. We need to insert all of them in mongodb and when done we need to continue. Since save row is an async operation, we will see how to go about it.


var mongoose = require('mongoose');
var conn = mongoose.createConnection('mongodb://127.0.0.1/blog');
var post_schema = mongoose.Schema({}, {
    strict: false,
    collection: 'post'
});
var post = conn.model('post', post_schema);

var records = [];
for (var i = 0; i < 10; i++) {
    records.push({
        title: 'Title Number ' + Math.random(1000),
        'cat_id': 1
    });
}


insertAndNotify(records, function(err) {
    if (err) {
        console.log(err);
        process.exit();
    }
    console.log('all done!!');
    process.exit();

    //continue all insert is done
});

function insertAndNotify(records, callback) {

    var inserted = 0;
    for (var i = 0; i < records.length; i++) {
        (function(row) {
            //anonymouse function for scope
            var new_post = new post({
                title: row.title,
                cat_id: row.cat_id * 1,
                date: new Date() + ""
            });
            new_post.save(function(err, row) {
                if (err) {
                    console.log(err);
                }
                else {
                    inserted++;
                    if (inserted == records.length) {
                        callback();
                    }
                }
            });
        })(records[i]);
    }
}

A Faster Mass Insert using async

In a previous blog post we have seen show to use async library. We will use that make a faster insert

function insertAndNotify(records, main_callback) {
    async.eachLimit(records, 5, function(row, callback) {
        var new_post = new post({
            title: row.title,
            cat_id: row.cat_id * 1,
            date: new Date() + ""
        });
        new_post.save(function(err, row) {
            if (err) {
                console.log(err);
                callback(err);
            }
            else {
                callback();
            }
        });
    }, function(err) {
        main_callback(err);
    });
}

In the above function, we are doing a parallel processing of 5 insert at a time hence will increase speed.
The same concept can be extended to remove and update as well.

We will see some of the advance operations which can be done using mongoose.

Load By ID

This is a very frequency use case where we need to find information based on ObjectID.
Below is the way to do it

Model.findOne({
            _id: mongoose.Types.ObjectId(model_id)
        }

Lean Models

When we do a find or findOne operation on collections, the result which we get a big mongoose object. Instead if you want to get bare bone json object here is the way to do it.

Model.find().lean().exec(function(err,result){
   console.log(result); //json object
});

Sort, Skip, Limit

There are various standard operations we can perform

Model.find().sort({date:-1}).skip(5).limit(10).exec(function(err,result){
});

$or condition

Another frequently used operation is the $or condition. All ‘where’ condition in mongo are by default ‘$and’ operations, if we want ‘$or’ we need to do something like this

Model.find({
    $or : [
       {isd : '54853e4e905437385a8b4567'},
       {store : '547ffe9c90543793128b4568'}   	
    ], 
    date : '2014-12-12'
})

So as per above where condition, isd & store are in $or , date is $and.