Software Ramblings
Node knockout tutorial 2, A primer for GridFS using the Mongo DB driver

A primer for GridFS using the Mongo DB driver

In the first tutorial we targeted general usage of the database. But Mongo DB is much more than this. One of the additional very useful features is to act as a file storage system. This is accomplish in Mongo by having a file collection and a chunks collection where each document in the chunks collection makes up a Block of the file. In this tutorial we will look at how to use the GridFS functionality and what functions are available.

A simple example

Let’s dive straight into a simple example on how to write a file to the grid using the simplified Grid class.

var mongo = require('mongodb'),
  Server = mongo.Server,
  Db = mongo.Db,
Grid = mongo.Grid;

var server = new Server('localhost', 27017, {auto_reconnect: true});
var db = new Db('exampleDb', server);

db.open(function(err, db) {
  if(!err) {
    var grid = new Grid(db, 'fs');    
    var buffer = new Buffer("Hello world");
    grid.put.(buffer, {metadata:{category:'text'}, content_type: 'text'}, function(err, fileInfo) {
      if(!err) {
        console.log("Finished writing file to Mongo");
      }
    });
  }
});

All right let’s dissect the example. The first thing you’ll notice is the statement

var grid = new Grid(db, 'fs');

Since GridFS is actually a special structure stored as collections you’ll notice that we are using the db connection that we used in the previous tutorial to operate on collections and documents. The second parameter ‘fs’ allows you to change the collections you want to store the data in. In this example the collections would be fs_files and fs_chunks.

Having a life grid instance we now go ahead and create some test data stored in a Buffer instance, although you can pass in a string instead. We then write our data to disk.

var buffer = new Buffer("Hello world");
grid.put.(buffer, {metadata:{category:'text'}, content_type: 'text'}, function(err, fileInfo) {
  if(!err) {
    console.log("Finished writing file to Mongo");
  }
});

Let’s deconstruct the call we just made. The put call will write the data you passed in as one or more chunks. The second parameter is a hash of options for the Grid class. In this case we wish to annotate the file we are writing to Mongo DB with some metadata and also specify a content type. Each file entry in GridFS has support for metadata documents which might be very useful if you are for example storing images in you Mongo DB and need to store all the data associated with the image.

One important thing is to take not that the put method return a document containing a _id, this is an ObjectID identifier that you’ll need to use if you wish to retrieve the file contents later.

Right so we have written out first file, let’s look at the other two simple functions supported by the Grid class.

the requires and and other initializing stuff omitted for brevity

db.open(function(err, db) {
  if(!err) {
    var grid = new Grid(db, 'fs');    
    var buffer = new Buffer("Hello world");
    grid.put.(buffer, {metadata:{category:'text'}, content_type: 'text'}, function(err, fileInfo) {        
      grid.get(fileInfo._id, function(err, data) {
        console.log("Retrieved data: " + data.toString());
        grid.delete(fileInfo._id, function(err, result) {
        });        
      });
    });
  }
});

Let’s have a look at the two operations get and delete

grid.get(fileInfo._id, function(err, data) {});

The get method takes an ObjectID as the first argument and as we can se in the code we are using the one provided in fileInfo._id. This will read all the chunks for the file and return it as a Buffer object.

The delete method also takes an ObjectID as the first argument but will delete the file entry and the chunks associated with the file in Mongo.

This api is the simplest one you can use to interact with GridFS but it’s not suitable for all kinds of files. One of it’s main drawbacks is you are trying to write large files to Mongo. This api will require you to read the entire file into memory when writing and reading from Mongo which most likely is not feasible if you have to store large files like Video or RAW Pictures. Luckily this is not the only way to work with GridFS. That’s not to say this api is not useful. If you are storing tons of small files the memory usage vs the simplicity might be a worthwhile tradeoff. Let’s dive into some of the more advanced ways of using GridFS.

Advanced GridFS or how not to run out of memory

As we just said controlling memory consumption for you file writing and reading is key if you want to scale up the application. That means not reading in entire files before either writing or reading from Mongo DB. The good news it’s supported. Let’s throw some code out there straight away and look at how to do chunk sized streaming writes and reads.

the requires and and other initializing stuff omitted for brevity

var fileId = new ObjectID();
var gridStore = new GridStore(db, fileId, "w", {root:'fs'});
gridStore.chunkSize = 1024 * 256;

gridStore.open(function(err, gridStore) {
 Step(
   function writeData() {
     var group = this.group();

     for(var i = 0; i < 1000000; i += 5000) {
       gridStore.write(new Buffer(5000), group());
     }   
   },

   function doneWithWrite() {
     gridStore.close(function(err, result) {
       console.log("File has been written to GridFS");
     });
   }
 )
});

Before we jump into picking apart the code let’s look at

var gridStore = new GridStore(db, fileId, "w", {root:'fs'});

Notice the parameter “w” this is important. It tells the driver that you are planning to write a new file. The parameters you can use here are.

  • “r” – read only. This is the default mode
  • “w” – write in truncate mode. Existing data will be overwritten
  • “w+” – write in edit mode

Right so there is a fair bit to digest here. We are simulating writing a file that’s about 1MB big to Mongo DB using GridFS. To do this we are writing it in chunks of 5000 bytes. So to not live with a difficult callback setup we are using the Step library with its’ group functionality to ensure that we are notified when all of the writes are done. After all the writes are done Step will invoke the next function (or step) called doneWithWrite where we finish up by closing the file that flushes out any remaining data to Mongo DB and updates the file document.

As we are doing it in chunks of 5000 bytes we will notice that memory consumption is low. This is the trick to write large files to GridFS. In pieces. Also notice this line.

gridStore.chunkSize = 1024 * 256;

This allows you to adjust how big the chunks are in bytes that Mongo DB will write. You can tune the Chunk Size to your needs. If you need to write large files to GridFS it might be worthwhile to trade of memory for CPU by setting a larger Chunk Size.

Now let’s see how the actual streaming read works.

var gridStore = new GridStore(db, fileId, "r");
gridStore.open(function(err, gridStore) {
  var stream = gridStore.stream(true);

  stream.on("data", function(chunk) {
    console.log("Chunk of file data");
  });

  stream.on("end", function() {
    console.log("EOF of file");
  });

  stream.on("close", function() {
    console.log("Finished reading the file");
  });
});

Right let’s have a quick lock at the streaming functionality supplied with the driver (make sure you are using 0.9.6-12 or higher as there is a bug fix for custom chunksizes that you need)

var stream = gridStore.stream(true);

This opens a stream to our file, you can pass in a boolean parameter to tell the driver to close the file automatically when it reaches the end. This will fire the close event automatically. Otherwise you’ll have to handle cleanup when you receive the end event. Let’s have a look at the events supported.

  stream.on("data", function(chunk) {
    console.log("Chunk of file data");
  });

The data event is called for each chunk read. This means that it’s by the chunk size of the written file. So if you file is 1MB big and the file has chunkSize 256K then you’ll get 4 calls to the event handler for data. The chunk returned is a Buffer object.

  stream.on("end", function() {
    console.log("EOF of file");
  });

The end event is called when the driver reaches the end of data for the file.

  stream.on("close", function() {
    console.log("Finished reading the file");
  });

The close event is only called if you the autoclose parameter on the gridStore.stream method as shown above. If it’s false or not set handle cleanup of the streaming in the end event handler.

Right that’s it for writing to GridFS in an efficient Manner. I’ll outline some other useful function on the Gridstore object.

Other useful methods on the Gridstore object

There are some other methods that are useful

gridStore.writeFile(filename/filedescriptor, function(err fileInfo) {});

writeFile takes either a file name or a file descriptor and writes it to GridFS. It does this in chunks to ensure the Eventloop is not tied up.

gridStore.read(length, function(err, data) {});

read/readBuffer lets you read a #length number of bytes from the current position in the file.

gridStore.seek(position, seekLocation, function(err, gridStore) {});

seek lets you navigate the file to read from different positions inside the chunks. The seekLocation allows you to specify how to seek. It can be one of three values.

  • GridStore.IOSEEKSET Seek mode where the given length is absolute
  • GridStore.IOSEEKCUR Seek mode where the given length is an offset to the current read/write head
  • GridStore.IOSEEKEND Seek mode where the given length is an offset to the end of the file

    GridStore.list(dbInstance, collectionName, {id:true}, function(err, files) {})

list lists all the files in the collection in GridFS. If you have a lot of files the current version will not work very well as it’s getting all files into memory first. You can have it return either the filenames or the ids for the files using option.

gridStore.unlink(function(err, result) {});

unlink deletes the file from Mongo DB, that’s to say all the file info and all the chunks.

This should be plenty to get you on your way building your first GridFS based application. As in the previous article the following links might be useful for you. Good luck and have fun.

Links and stuff

Node knockout tutorial 1, A Basic introducton to Mongo DB

A Basic introduction to Mongo DB

Mongo DB has rapidly grown to become a popular database for web applications and is a perfect fit for Node.JS applications, letting you write Javascript for the client, backend and database layer. It’s schemaless nature is a better match to our constantly evolving data structures in web applications and the integrated support for location queries a bonus that it’s hard to ignore. Throw Replicasets for scaling and we are looking at really nice platform to grow your storage needs now and in the future.

Now to shamelessly plug my driver. It can be downloaded either using npm or fetched from the github repository. To install via npm do the following.

npm install mongodb

or go fetch it from github at https://github.com/christkv/node-mongodb-native

Once this business is taken care of let’s move through the types available for the driver and then how to connect to your Mongo DB instance before facing the usage of some crud operations.

Mongo DB data types

So there is an important thing to keep in mind when working with Mongo DB and that is that there is a slight mapping difference between the types supported in Mongo DB and what is native types in Javascript. Let’s have a look at the types supported out of the box and then how types are promoted by the driver to try to fit as close to the native Javascript types as possible.

  • Float is a 8 byte and is directly convertible to the Javascript type Number
  • Double class a special class representing a float value, this is especially useful when using capped collections where you need to ensure your values are always floats.
  • Integers is a bit trickier due to the fact that Javascript represents all Numbers as 64 bit floats meaning that the maximum integer value is at a 53 bit. Mongo has two types for integers, a 32 bit and a 64 bit. The driver will try to fit the value into 32 bits if it can and promote it to 64 bits if it has to. Similarly it will deserialize attempting to fit it into 53 bits if it can. If it cannot it will return an instance of Long to avoid loosing precession.
  • Long class a special class that let’s you store 64 bit integers and also let’s you operate on the 64 bits integers.
  • Date maps directly to a Javascript Date
  • RegEp maps directly to a Javascript RegExp
  • String maps directly to a Javascript String (encoded in utf8)
  • Binary class a special class that let’s you store data in Mongo DB
  • Code class a special class that let’s you store javascript functions in Mongo DB, can also provide a scope to run the method in
  • ObjectID class a special class that holds a MongoDB document identifier (the equivalent to a Primary key)
  • DbRef class a special class that let’s you include a reference in a document pointing to another object
  • Symbol class a special class that let’s you specify a symbol, not really relevant for javascript but for languages that supports the concept of symbols.

As we see the number type can be a little tricky due to the way integers are implemented in Javascript. The latest driver will do correct conversion up to 53 bit’s of complexity. If you need to handle big integers the recommendation is to use the Long class to operate on the numbers.

Getting that connection to the database

Let’s get around to setting up a connection with the Mongo DB database. Jumping straight into the code let’s do direct connection and then look at the code.

var mongo = require('mongodb'),
  Server = mongo.Server,
  Db = mongo.Db;

var server = new Server('localhost', 27017, {auto_reconnect: true});
var db = new Db('exampleDb', server);

db.open(function(err, db) {
  if(!err) {
    console.log("We are connected");
  }
});

Let’s have a quick look at the simple connection. The new Server(…) sets up a configuration for the connection and the auto_reconnect tells the driver to retry sending a command to the server if there is a failure. Another option you can set is poolSize, this allows you to control how many tcp connections are opened in parallel. The default value for this is 1 but you can set it as high as you want. The driver will use a round-robin strategy to dispatch and read from the tcp connection.

We are up and running with a connection to the database. Let’s move on and look at what collections are and how they work.

Mongo DB and Collections

Collections are the equivalent of tables in traditional databases and contain all your documents. A database can have many collections. So how do we go about defining and using collections. Well there are a couple of methods that we can use. Let’s jump straight into code and then look at the code.

the requires and and other initializing stuff omitted for brevity

db.open(function(err, db) {
  if(!err) {
    db.collection('test', function(err, collection) {});

    db.collection('test', {safe:true}, function(err, collection) {});

    db.createCollection('test', function(err, collection) {});

    db.createCollection('test', {safe:true}, function(err, collection) {});
  }
});  

Three different ways of creating a collection object but slightly different in behavior. Let’s go through them and see what they do

db.collection('test', function(err, collection) {});

This function will not actually create a collection on the database until you actually insert the first document.

db.collection('test', {safe:true}, function(err, collection) {});

Notice the {safe:true} option. This option will make the driver check if the collection exists and issue an error if it does not.

db.createCollection('test', function(err, collection) {});

This command will create the collection on the Mongo DB database before returning the collection object. If the collection already exists it will ignore the creation of the collection.

db.createCollection('test', {safe:true}, function(err, collection) {});

The {safe:true} option will make the method return an error if the collection already exists.

With an open db connection and a collection defined we are ready to do some CRUD operation on the data.

And then there was CRUD

So let’s get dirty with the basic operations for Mongo DB. The Mongo DB wire protocol is built around 4 main operations insert/update/remove/query. Most operations on the database are actually queries with special json objects defining the operation on the database. But I’m getting ahead of myself. Let’s go back and look at insert first and do it with some code.

the requires and and other initializing stuff omitted for brevity

db.open(function(err, db) {
  if(!err) {
    db.collection('test', function(err, collection) {
      var doc1 = {'hello':'doc1'};
      var doc2 = {'hello':'doc2'};
      var lotsOfDocs = [{'hello':'doc3'}, {'hello':'doc4'}];

      collection.insert(doc1);

      collection.insert(doc2, {safe:true}, function(err, result) {});

      collection.insert(lotsOfDocs, {safe:true}, function(err, result) {});
    });
  }
});

A couple of variations on the theme of inserting a document as we can see. To understand why it’s important to understand how Mongo DB works during inserts of documents.

Mongo DB has asynchronous insert/update/remove operations. This means that when you issue an insert operation its a fire and forget operation where the database does not reply with the status of the insert operation. To retrieve the status of the operation you have to issue a query to retrieve the last error status of the connection. To make it simpler to the developer the driver implements the {safe:true} options so that this is done automatically when inserting the document. {safe:true} becomes especially important when you do update or remove as otherwise it’s not possible to determine the amount of documents modified or removed.

Now let’s go through the different types of inserts shown in the code above.

collection.insert(doc1);

Taking advantage of the async behavior and not needing confirmation about the persisting of the data to Mongo DB we just fire off the insert (we are doing live analytics, loosing a couple of records does not matter).

collection.insert(doc2, {safe:true}, function(err, result) {});

That document needs to stick. Using the {safe:true} option ensure you get the error back if the document fails to insert correctly.

collection.insert(lotsOfDocs, {safe:true}, function(err, result) {});

A batch insert of document with any errors being reported. This is much more efficient if you need to insert large batches of documents as you incur a lot less overhead.

Right that’s the basics of insert’s ironed out. We got some documents in there but want to update them as we need to change the content of a field. Let’s have a look at a simple example and then we will dive into how Mongo DB updates work and how to do them efficiently.

the requires and and other initializing stuff omitted for brevity

db.open(function(err, db) {
  if(!err) {
    db.collection('test', function(err, collection) {
      var doc = {mykey:1, fieldtoupdate:1};

      collection.insert(doc, {safe:true}, function(err, result) {
        collection.update({mykey:1}, {$set:{fieldtoupdate:2}}, {safe:true}, function(err, result) {});      
      });

      var doc2 = {mykey:2, docs:[{doc1:1}]};

      collection.insert(doc2, {safe:true}, function(err, result) {
        collection.update({mykey:2}, {$push:{docs:{doc2:1}}, {safe:true}, function(err, result) {});
      });
    });
  };
});

Alright before we look at the code we want to understand how document updates work and how to do the efficiently. The most basic and less efficient way is to replace the whole document, this is not really the way to go if you want to change just a field in your document. Luckily Mongo DB provides a whole set of operations that let you modify just pieces of the document Atomic operations documentation. Basically outlined below.

  • $inc – increment a particular value by a certain amount
  • $set – set a particular value
  • $unset – delete a particular field (v1.3+)
  • $push – append a value to an array
  • $pushAll – append several values to an array
  • $addToSet – adds value to the array only if its not in the array already
  • $pop – removes the last element in an array
  • $pull – remove a value(s) from an existing array
  • $pullAll – remove several value(s) from an existing array
  • $rename – renames the field
  • $bit – bitwise operations

Now that the operations are outline let’s dig into the specific cases show in the code example.

collection.update({mykey:1}, {$set:{fieldtoupdate:2}}, {safe:true}, function(err, result) {});

Right so this update will look for the document that has a field mykey equal to 1 and apply an update to the field fieldtoupdate setting the value to 2. Since we are using the {safe:true} option the result parameter in the callback will return the value 1 indicating that 1 document was modified by the update statement.

collection.update({mykey:2}, {$push:{docs:{doc2:1}}, {safe:true}, function(err, result) {});

This updates adds another document to the field docs in the document identified by {mykey:2} using the atomic operation $push. This allows you to modify keep such structures as queues in Mongo DB.

Let’s have a look at the remove operation for the driver. As before let’s start with a piece of code.

the requires and and other initializing stuff omitted for brevity

db.open(function(err, db) {
  if(!err) {
    db.collection('test', function(err, collection) {
      var docs = [{mykey:1}, {mykey:2}, {mykey:3}];

      collection.insert(docs, {safe:true}, function(err, result) {

        collection.remove({mykey:1});

        collection.remove({mykey:2}, {safe:true}, function(err, result) {});

        collection.remove();
      });
    });
  };
});

Let’s examine the 3 remove variants and what they do.

collection.remove({mykey:1});

This leverages the fact that Mongo DB is asynchronous and that it does not return a result for insert/update/remove to allow for synchronous style execution. This particular remove query will remove the document where mykey equals 1.

collection.remove({mykey:2}, {safe:true}, function(err, result) {});

This remove statement removes the document where mykey equals 2 but since we are using {safe:true} it will back to Mongo DB to get the status of the remove operation and return the number of documents removed in the result variable.

collection.remove();

This last one will remove all documents in the collection.

Time to Query

Queries is of course a fundamental part of interacting with a database and Mongo DB is no exception. Fortunately for us it has a rich query interface with cursors and close to SQL concepts for slicing and dicing your datasets. To build queries we have lots of operators to choose from Mongo DB advanced queries. There are literarily tons of ways to search and ways to limit the query. Let’s look at some simple code for dealing with queries in different ways.

the requires and and other initializing stuff omitted for brevity

db.open(function(err, db) {
  if(!err) {
    db.collection('test', function(err, collection) {
      var docs = [{mykey:1}, {mykey:2}, {mykey:3}];

      collection.insert(docs, {safe:true}, function(err, result) {

        collection.find().toArray(function(err, items) {});

        var stream = collection.find({mykey:{$ne:2}}).streamRecords();
        stream.on("data", function(item) {});
        stream.on("end", function() {});

        collection.findOne({mykey:1}, function(err, item) {});

      });
    });
  };
});

Before we start picking apart the code there is one thing that needs to be understood, the find method does not execute the actual query. It builds an instance of Cursor that you then use to retrieve the data. This lets you manage how you retrieve the data from Mongo DB and keeps state about your current Cursor state on Mongo DB. Now let’s pick apart the queries we have here and look at what they do.

collection.find().toArray(function(err, items) {});

This query will fetch all the document in the collection and return them as an array of items. Be careful with the function toArray as it might cause a lot of memory usage as it will instantiate all the document into memory before returning the final array of items. If you have a big resultset you could run into memory issues.

var stream = collection.find({mykey:{$ne:2}}).streamRecords();
stream.on("data", function(item) {});
stream.on("end", function() {});

This is the preferred way if you have to retrieve a lot of data for streaming, as data is deserialized a data event is emitted. This keeps the resident memory usage low as the documents are streamed to you. Very useful if you are pushing documents out via websockets or some other streaming socket protocol. Once there is no more document the driver will emit the end event to notify the application that it’s done.

collection.findOne({mykey:1}, function(err, item) {});

This is special supported function to retrieve just one specific document bypassing the need for a cursor object.

That’s pretty much it for the quick intro on how to use the database. I have also included a list of links to where to go to find more information and also a sample crude location application I wrote using express JS and mongo DB.

Links and stuff

Ad people bullshitting (Taken with Instagram at Fira de Barcelona)

Ad people bullshitting (Taken with Instagram at Fira de Barcelona)

Dinner for speakers (Taken with Instagram at Las caballerizas)

Dinner for speakers (Taken with Instagram at Las caballerizas)

Wild boar (Taken with instagram)

Wild boar (Taken with instagram)

Offsite xing (Taken with Instagram at Denmark)

Offsite xing (Taken with Instagram at Denmark)

Calcotada (Taken with Instagram at Torredembarra)

Calcotada (Taken with Instagram at Torredembarra)

Offsite (Taken with Instagram at Sitges, Cataluña, Spain)

Offsite (Taken with Instagram at Sitges, Cataluña, Spain)

Nodejs Mongodb driver Tutorial 0

Connecting using the database driver

The first step when connecting to the mongodb is to create a new db object.

var db = new Db('test', new Server("127.0.0.1", 27017, {auto_reconnect: true}), {});


The format for the new statement is as follows

new Db(database name, server configuration, options)

The different fields in the new statement do the following

The database name is the mongodb database that you want this connection be for. The sever configuration is the server information for where you want to connect. There are a couple of differnt types of Server configurations available.

  • Server: The single server connection
  • ServerPair: A master-slave server setup
  • ServerCluster: A cluster of master-slave servers
  • ReplSetServers: A very experiemental replica set class contributed (at your own risk)

The options for the database connection

  • strict (boolean, default false): If strict is set to true the driver will call back to the mongodb driver after each operation to check the status of the operation.
  • pk: If you wish to override the automatic creation of ids for new objects that are inserted pass in an instance of a key factory.
  • native_parser: (boolean, default false): Allows you to specify if you want to use the c++ bson parser instead of the default javascript implementation, can provide a performance boost at the cost of stability.


Once you have created an object it’s time to connect to the database.

db.open(function(err, db) {
    // Database is open
});


Here we get to the crux of nodjs. Since nodejs is completely asynchronous we need to provide a callback for the open call because the driver will go through a couple of steps calling and responding to the mongodb driver to set up the connection. This can be quite confusing for people who come from synchronous environments as they expect something like this.

var db = db.open();


However the problem with this approach would be that you would keep executing code in nodejs without waiting for the db to finish setting up the connection. Thus this code.

var db = db.open();
db.collectionsInfo('mycollection', function(err, collectionInfo) {
    // Got collection info;
});


This coudle would most likely fail as the connection was not ready before you executed a command over the connection. By using the callback style it enforces the right state of the connection and ensures your code works as designed. This also leads to one of the main confusions with early adapters who play around with the mongodb cli. The cli uses blocking calls for it’s operations adding to the confusion when they move to using nodejs and find themselves with the need for callbacks.

Authenticating Now let’s look at the other part of creating a connection. Opening a connection and then authenticating against mongodb for those locked down databases. In Mongodb you can have databases that are password protected. There is as for now not a massively complicated ACL system for mongodb and I hope it never will have that. They do however provide a simple user/password authentication scheme so you can look down access to databases in the mongodb. To connect using the nodejs driver we do the following.

var db = new Db('test', new Server("127.0.0.1", 27017, {auto_reconnect: true}), {});
db.open(function(err, db) {
    db.authenticate('admin', 'admin', function(err, result) {
         // Authenticated
    });
});


If you don’t get an error object back you are ready to work on you database, otherwise you’ll get an error message providing you with an authenication error. To add or remove a user (once you are authenticated or on a non-locked down database) use the following two methods

db.addUser(username, password, function(err, result){});
db.removeUser(username, function(err, results){});


Right let’s have a quick look on how we use these methods together in a complete sequence.

var db = new Db('test', new Server("127.0.0.1", 27017, {auto_reconnect: true}), {});
db.open(function(err, db) {
    db.addUser('admin', 'admin', function(err, result) {
         db.authenticate('admin', 'admin', function(err, result) {
              db.removeUser('admin', 'admin', function(err, result) {
                   // Done
              });
          });

    });
});


Right we have learned how to connect to a mongodb server and also once we are connected how to authenticate the connction or add/remove authentication from a database. So let’s look at a simpler way of doing the authenication (curtesy of your helpful community, not my lazy ass).

The easy connection The community contributed a simpler way to do this above for when you only need a single server connection. This method is called connect and takes a url to allow you to specify a connection without having to nest calls. The calling format is.

Db.connect(url, callback)


Where the url has to be in the following format

mongodb://server:port/databasename


or

mongodb://user:password@server:port/databasename


So to do a localhost connection with no authentication do the following.

Db.connect("mongodb://localhost:27017/mydatabase", function(err, db) {
});


Or with authentication included.

Db.connect("mongodb://admin:admin@localhost:27017/mydatabase", function(err, db) {
});


This will also allow you to connect to mongodb service providers such as mongohq and other ones (as long as they follow the standard mongodb protocols).

That wraps up this tutorial focusing on the basics of opening and authenticating against mongodb using the nodejs driver. The next tutorial will focus on simple crud operations such as insert, update, delete and find.

Carnaval in Sitges (Taken with Instagram at Sitges)

Carnaval in Sitges (Taken with Instagram at Sitges)