I am Hack Sparrow
Captain of the Internets.

Mongoskin Tutorial with Examples

Mongoskin Tutorial


Mongoskin is probably the most developer-friendly MongoDB driver for Node.js at the moment - it is asynchronous and has a clean looking structure. But its docs are not that developer-friendly (the effort is much appreciated though) - no good examples or explanation; probably because English isn't the author's first language.

After realizing that the Mongoskin docs may take a long time to improve, I decided to personally address the issue by writing a Mongoskin tutorial for all those who are looking for an easy way to integrate MongoDB with Node.js. This is going to be a beginner's tutorial which will guide you through the basics of Mongoskin and should be enough for all basic Node.js-MongoDB interaction.

To give credit where it is due, Mongoskin is built on top of MongoDB Native. The underlying magic behind Mongoskin is MongoDB Native, all Mongoskin does is make the magic wieldier.

If you are not that familiar with MongoDB, I would highly recommend that you first go through this MongoDB tutorial so that you know the basics of MongoDB, and what to expect from Mongoskin.

We will start this tutorial by installing Mongoskin:

$ npm install mongoskin

You may see this message when you install Mongoskin:

To install with C++ bson parser do <npm install mongodb --mongodb:native>

Don't worry too much about it. That's a message from MongoDB Native, and the C++ BSON parser is now actually deprecated as the JavaScript parser has improved a lot. Just disregard that message.

Now let's create a database on the MongoDB server using the mongo shell so that we can work our examples on it. We'll name the database rockband, it is going to be about a bunch of rock bands.

$ mongo
> use rockband
> db.bands.insert({name: 'Hollywood Rose', members: ['Axl Rose', 'Izzy Stradlin', 'Chris Weber'], year: 1984})
> db.bands.insert({name: 'Road Crew', members: ['Slash', 'Steven Adler', 'Duff McKagan'], year: 1984})
> db.bands.insert({name: 'L.A. Guns', members: ['Tracy Guns', 'Paul Black', 'Mick Cripps', 'Nickey Alexander'], year: 1985})
> db.bands.insert({name: "Velvet Revolver", members: ['Scott Weiland', 'Slash', 'Dave Kushner', 'Matt Sorum', 'Duff McKagan'], year: 2002})

In the above mongo commands, we have made four entries to the collection named bands in the database named rockband.

Now it is time to include the Mongoskin module in your script, you do it this way:

var db = require('mongoskin').db('localhost:27017/rockband'); 

That creates an instance of a connection to MongoDB, by default it is connected to the database rockband. I have named the instance db, so as to keep it consistent with the MongoDB's commandline db object. Henceforth all instances of db is a reference to the instance we created here.

Now what if you need to authenticate to connect to the database? Authentication using Mongoskin is easy, just include the auth creds in the instantiation code like this:

var db = require('mongoskin').db('dewey:tehrock@localhost:27017/rockband');

where "dewey" is the username, and "tehrock" is the password.

The rest of the tutorial will show mongo commands and their equivalents in Mongoskin. If you don't know the basics of MongoDB, you will probably find it hard to follow the examples, so make sure you have gone through the MongoDB tutorial I wrote.

To see the existing data in a collection:

> db.bands.find()

In Mongoskin, it's done this way:

db.collection('bands').find().toArray(function(err, result) {
    if (err) throw err;
    console.log(result);
});

We use the toArray() function to convert the Mongoskin cursor to developer-friendly Array.

So what's the non-toArray() way? Here it is:

db.collection('bands').find({}, function(err, result) {
    result.each(function(err, band) {
        console.log(band);
    });
});

result in this case is not an Array but a Mongoskin cursor, you need to use the each() function to iterate through it.

There is another way of do the same, it doesn't use a callback function, looks 'dirtier', and not recommended at all:

var bands = db.collection('bands').find({});
bands.each(function(err, band) {
    console.log(band);
});

To those wondering if there's any difference between find() and find({}), there is no difference. find() is understood as passing an empty object.

To select only one item from a collection:

> db.bands.findOne()

The Mongoskin way:

db.collection('bands').findOne(function(err, result) {
    if (err) throw err;
    console.log(result);
});

Note: we don't convert the result of the above command to Array because there is only one result, if any.

Now let's add another document to the collection:

> db.bands.insert({name: "Guns N' Roses", members: ['Axl Rose', 'Slash', 'Izzy Stradlin', 'Matt Sorum', 'Duff McKagan'], year: 1986});

To do the same in Mongoskin:

db.collection('bands').insert({name: "Guns N' Roses", members: ['Axl Rose', 'Slash', 'Izzy Stradlin', 'Matt Sorum', 'Duff McKagan'], year: 1986}, function(err, result) {
    if (err) throw err;
    if (result) console.log('Added!');
});

I need to replace the member Matt Sorum with Steven Adler. This is how it would be done from the mongo shell:

> db.bands.update({name:"Guns N' Roses"}, {'$pull':{members:'Matt Sorum'}})
> db.bands.update({name:"Guns N' Roses"}, {'$push':{members:'Steven Adler'}})

And this is how it is done from Mongoskin:

db.collection('bands').update({name:"Guns N' Roses"}, {'$pull':{members:'Matt Sorum'}}, function(err) {
    if (err) throw err;
    db.collection('bands').update({name:"Guns N' Roses"}, {'$push':{members:'Steven Adler'}}, function(err) {
        if (err) throw err;
        console.log('Updated!');
    });
});

Notice how the Mongoskin code is quite similar to that of the mongo shell command. Instead of bands, we have collection('bands'), and we pass a callback function; rest of the it is the same. Most of the Mongoskin functions maintain the similarity with mongo commandline as closely as possible, that's the beauty of Mongoskin, if you are familiar with the commandline version, you can almost guess the Mongoskin version of a command. If there are parameters involved, just pass them as you would in the mongo commandline (works for most of the functions).

Now let's how we do some conditional selections in Mongoskin.

To get the band with the name "Road Crew", we'd do this in mongo shell:

> db.bands.find({name:'Road Crew'})

and this in Mongoskin:

db.collection('bands').find({name:'Road Crew'}).toArray(function(err, result) {
    console.log('Band members of Road Crew');
    console.log(result[0].members);
});

If we know that we can expect a single result, we could use the findOne() function instead of find():

db.collection('bands').findOne({name:'Road Crew'}, function(err, result) {
    console.log('Band members of Road Crew');
    console.log(result.members);
});

Tip: db.collection('bands') could be stored in a variable named bands to make our Mongoskin code leaner, so let's do that:

var bands = db.collection('bands');

Now let's do a count() on the collection:

> db.bands.count()
> db.bands.count({year:{$gte:1985}})

In Mongoskin:

bands.count(function(err, count) {
    console.log('There are ' + count + ' bands in the database');
});

bands.count({year:{$gte:1985}}, function(err, count) {
    console.log(count + ' bands were formed in 1985 or later');
});

Now let's try an updating a document:

From the mongo shell:

> db.bands.update({name:'Hollywood Rose'}, {$set:{year:1983}})

Mongoskin code:

bands.update({name:'Hollywood Rose'}, {$set:{year:2000}}, function(err, result) {
    if (!err) console.log('Year updated!');
});

Deleting a record is a no-brainer. The mongo shell way:

> db.bands.remove({name:'Velvet Revolver'})

The Mongoskin way:

db.collection('bands').remove({name:'Velvet Revolver'}, function(err, result) {
    if (!err) console.log('VR deleted!');
});

Tip: you might get confused, was it remove() or delete()? Remember that delete is a JavaScript reserved keyword, it cannot be used as a function or variables name, hence remove() is the one!

In case you are using the default _id generated by MongoDB, and want to select a document by its _id; doing this way won't get you the result:

{_id: '4f5bc53f3d0b5eb764000002'}

This is the right way:

{_id: db.ObjectID.createFromHexString('4f5bc53f3d0b5eb764000002')}

That's it for today. There is more to Mongoskin than the examples I have shown in this tutorial. I will be covering the more technical aspects of Mongoskin in dedicated tutorials rather than including everything here and making it a boring read. Did I miss anything? Want to know anything? Ping me in the comments, if it is within to the scope of this tutorial I will update it from your feedback, else I'll cover them in a more technical Mongoskin tutorial.

27 Responses to “Mongoskin Tutorial with Examples”

  1. Manos says:

    Thanks for the tutorial. One suggestion: It would be nice if you could add an example of using .group().

  2. dYb says:

    awesome!!
    btw, the update() method updates a SINGAL document, but by using the __multi__ option

  3. jerry says:

    Hi !

    This tutorial is clear! Thank you!
    I get a trouble about I need to response the results with multiple query, such as

    the request will be
    {
    “productinfo”:[
    {"modelname": "AB1234"},
    {"modelname": "RT5678"},
    {"modelname": "VC1357"}
    ]
    }

    then I write my code such as

    for (var index = 0; index < req.body.productinfo.length; index++) {
    db.collection('productinfo').find({modelname:req.body.productInfo[index].modelname}, {_id:false}).toArray(function (err, items) {
    items.forEach(function(value) {
    RESPONSE_BODY.productinfo.push(value);
    });
    response(res, JSON.stringify(RESPONSE_BODY));
    });
    }

    but it will only response the first query result, and return the following message

    events.js:72
    throw er; // Unhandled 'error' event
    ^
    Error: Can't render headers after they are sent to the client.
    at ServerResponse.OutgoingMessage._renderHeaders (http.js:749:11)
    at ServerResponse.res._renderHeaders (/home/jerrykuo/nodejs/portal/node_modules/express/node_modules/connect/lib/patch.js:69:27)
    at ServerResponse.writeHead (http.js:1131:20)
    at ServerResponse.res.writeHead (/home/jerrykuo/nodejs/portal/node_modules/express/node_modules/connect/lib/patch.js:75:22)
    at response (/home/jerrykuo/nodejs/portal/service/firmwareinfo.js:13:7)
    at /home/jerrykuo/nodejs/portal/service/firmwareinfo.js:51:6
    at /home/jerrykuo/nodejs/portal/node_modules/mongodb/lib/mongodb/cursor.js:158:16
    at commandHandler (/home/jerrykuo/nodejs/portal/node_modules/mongodb/lib/mongodb/cursor.js:651:16)
    at /home/jerrykuo/nodejs/portal/node_modules/mongodb/lib/mongodb/db.js:1670:9
    at Server.Base._callHandler (/home/jerrykuo/nodejs/portal/node_modules/mongodb/lib/mongodb/connection/base.js:382:41)

    I know it's due to I return the result at the first query with response(), but if I put the response() behind the for loop , It will return nothing.
    Could you give me some advice about this!

    Thanks.

  4. amrutraj says:

    Hi,
    What is “result” in

    bands.update({name:’Hollywood Rose’}, {$set:{year:2000}}, function(err, result) {
    if (!err) console.log(‘Year updated!’);
    });

    . When i tried it, came out as undefined.

    Q: Is there any way to retrieve the updated entry without making another query?

  5. thayanban says:

    thanks alot.

  6. thayanban says:

    Very usefull tutorial.An humble request.I’m begginer to node.js and mongoskin.And i need to know how can i use mongoskin to upload image files.(i.e what are the changes i need to made in the above insert query).

  7. thayanban says:

    i’m using node.js express

Make a Comment