Tag Archives: MongoDB

MEAN web development #7: MongoDB and Mongoose

Last week we’ve seen some of the basic functionality of AngularJS, at least enough to get you started. Before that we’ve seen Node.js and Express. So that’s EAN and we’re left with the M. Well, Dial M for MongoDB because that’s what we’re going to look at this week.

  1. MEAN web development #1: MEAN, the what and why
  2. MEAN web development #2: Node.js in the back
  3. MEAN web development #3: More Node.js
  4. MEAN web development #4: All aboard the Node.js Express!
  5. MEAN web development #5: Jade and Express
  6. MEAN web development #6: AngularJS in the front
  7. MEAN web development #7: MongoDB and Mongoose
  8. MEAN web development #8: Sockets will rock your socks!
  9. MEAN web development #9: Some last remarks

As usual you can find the examples for this post on my GitHub page in the mean7-blog repository.

Hello persistent data

I’ve already written an entire post on NoSQL and MongoDB, A first look at NoSQL and MongoDB in particular. I’ve already told you to read it in the first part of this series, MEAN web development #1: MEAN, the what and why. If you haven’t read either of those I suggest you do so before continuing because I won’t repeat how to install MongoDB and MongoVUE. Don’t worry I’ll wait…

Before we continue I should mention that everything we’re going to do is async. That means lots of callback functions. We don’t want to block our main thread after all! It also means that the callbacks may not be called in the same order as their ‘parent functions’ are. Or that the records are actually inserted before we query them! Because I wanted to keep it simple in the complete example file I haven’t nested all examples in callbacks, but keep in mind that you may get some odd results. It worked fine for me by the way, if you get some weird results try running the examples one by one (simply commenting out the others).

So let’s just get a Node.js server up and running and write some data to the database real quick! You’ll be surprised how easy it is. First of all install the MongoDB driver using npm (npm install mongodb).
Next we’ll make a connection to our MongoDB instance.

var app = require('express')();
var MongoClient = require('mongodb').MongoClient;
     
var urlWithCreds = 'mongodb://user:password@localhost:27017/local';
var url = 'mongodb://localhost:27017/local';
MongoClient.connect(url, function (err, db) {
    if (err) {
        console.log(err);
    } else {
        console.log('Connected to the database.');
        db.close();
    }
});
var server = app.listen(80, '127.0.0.1');

So first of all we require Express (which isn’t necessary for MongoDB) and MongoDB. We take the MongoClient property of the MongoDB module. We use this client to connect to the database using the connect function, which takes a URI and a callback function. The callback has a MongoError (in case you can’t log in, for example if you have wrong credentials) and a Db as parameters.
We can use the Db object to do all kinds of stuff like creating and dropping databases, collections and indices and do our CRUD operations (Create, Read, Update, Delete). Let’s insert a simple object.

var url = 'mongodb://localhost:27017/local';
MongoClient.connect(url, function (err, db) {
    if (err) {
        console.log(err);
    } else {
        var artist = {
            name: 'Massive Attack',
            countryCode: 'GB'
        };
        var collection = db.collection('artists');
        collection.insertOne(artist);
        console.log(artist._id);
        db.close();
    }
});

As you can see we use the db parameter to get a collection (the MongoDB variant of a database table) using the collection function. If the collection does not exist it will create one automatically. We can then simply insert an object using the insertOne function of the collection. Now something funny has happened. After calling insertOne our artist object suddenly has an _id property. MongoDB uses this _id to uniquely identify objects.
So that wasn’t so bad right? Let’s look at other CRUD functionality!

CRUD with MongoDB

So let’s retrieve the record we just inserted. We can do this using the findOne function of the collection.

MongoClient.connect(url, function (err, db) {
    if (err) {
        console.log(err);
    } else {
        var collection = db.collection('artists');
        collection.findOne({ name: 'Massive Attack' }, function (err, artist) {
            if (err) {
                console.log(err);
            } else {
                console.log(artist);
            }
            db.close();
        });
    }
});

So the object that is passed to the findOne function is actually a search parameter. In this case we’re looking for documents (or records) that have a name equal to ‘Massive Attack’. The second parameter is a callback function that gives us an error, if any occurred, and the document that was retrieved. If you ran the previous example multiple times Massive Attack will be in your database more than once (having different values for _id), in this case findOne simply returns the first document it finds.

So let’s insert a few more artists, just so we’ve got a little set to work with. We can use the insertMany function for this.

collection.insertMany([
{
    name: 'The Beatles',
    countryCode: 'GB',
    members: [
        'John Lennon',
        'Paul McCartney',
        'George Harrison',
        'Ringo Starr'
    ]
},
{
    name: 'Justin Bieber',
    countryCode: 'No one wants him'
},
{
    name: 'Metallica',
    countryCode: 'USA'
},
{
    name: 'Lady Gaga',
    countryCode: 'USA'
}
], function (err, result) {
    if (err) {
        console.log(err);
    } else {
        console.log(result);
    }
});

Now you may think there’s a findMany function as well, but it’s actually just called find. find returns a Cursor which is something like an array, but not quite. We can use the toArray method though. The find function has a query parameter which is just an object that describes what fields of a document must have which values. We can search fields with AND, OR, NOT, IN, greater than, lesser than, regular expressions and everything you’re used to in SQL databases.

var findCallback = function (err, artists) {
    if (err) {
        console.log(err);
    } else {
        console.log('\n\nFound artists:');
        artists.forEach(function (a) {
            console.log(a);
        });
    }
};

// All documents.
collection.find().toArray(findCallback);

// Name not equal to Justin Bieber.
collection.find({ name: { $ne: 'Justin Bieber' } }).toArray(findCallback);

// Name equal to Massive Attach or name equal to The Beatles.
collection.find({ $or: [{ name: 'Massive Attack' }, { name: 'The Beatles' }] }).toArray(findCallback);

// Members contains John Lennon.
collection.find({ members: 'John Lennon' }).toArray(findCallback);

Now let’s update a record.

collection.findOneAndUpdate({ name: 'Massive Attack' },
    { $set: {
        cds: [
            {
                title: 'Collected',
                year: 2006,
                label: {
                    name: 'Virgin'
                },
                comment: 'Best Of'
            },
            {
                title: 'Mezzanine',
                year: 1998,
                label: 'Virgin'
            },
            {
                title: 'No Protection: Massive Attack v Mad Professor',
                year: 1995,
                label: 'Circa Records',
                comment: 'Remixes'
            },
            {
                title: 'Protection',
                year: 1994,
                label: {
                    name: 'Circa'
                }
            }
        ]
        }
    }, function (err, result) {
    console.log('\n\nUpdated artist:');
    if (err) {
        console.log(err);
    } else {
        console.log(result);
    }
});

Here we see the findOneAndUpdate in action. Alternatively we could’ve used updateOne. And for multiple updates we can use updateMany.

Now let’s delete a record. There’s one guy I really don’t want in my database (yes, I’ve added him so I wouldn’t feel guilty about deleting him).  And for this we can, of course, use findOneAndDelete.

collection.findOneAndDelete({ name: 'Justin Bieber' }, function (err, result) {
    console.log('\n\nDeleted artist:');
    if (err) {
        console.log(err);
    } else {
        console.log(result);
    }
});

Really no surprises there. Alternatively there’s deleteOne and to delete many use, you guessed it, deleteMany.

Mongoose

So MongoDB with Node.js looks really good, right? It wasn’t very hard to use. It’s really just a matter of working with JavaScript objects. And as we all know JavaScript objects are very dynamic. In the previous examples we’ve already seen that some artists have a member property defined and then when we updated we all of a sudden had a cds property and some CD’s have a comment while others don’t… And MongoDB has no problem with it at all. We just save and fetch what is there.

Now try this.

var app = require('express')();
var MongoClient = require('mongodb').MongoClient;

var Artist = function (name, activeFrom, activeTo) {
    if (!(this instanceof Artist)) {
       return new Artist(name, activeFrom, activeTo);
    }
    var self = this;
    self.name = name;
    self.activeFrom = activeFrom;
    self.activeTo = activeTo;
    self.yearsActive = function () {
        if (self.activeTo) {
            return self.activeTo - self.activeFrom;
        } else {
            return new Date().getFullYear() - self.activeFrom;
        }
    };
};

var url = 'mongodb://localhost:27017/local';
MongoClient.connect(url, function (err, db) {
    if (err) {
        console.log(err);
    } else {
        var collection = db.collection('artists');
        // Empty the collection
        // so the next examples can be run more than once.
        collection.deleteMany();
        
        var massiveAttack = new Artist('Massive Attack', 1988);
        console.log('\n\n' + massiveAttack.name + ' has been active for ' + massiveAttack.yearsActive() +  ' years.');
        
        collection.insertOne(massiveAttack);
        
        collection.findOne({ name: massiveAttack.name }, function (err, result) {
            if (err) {
                console.log(err);
            } else {
                try {
                    console.log('\n\n' + result.name + ' has been active for ' + result.yearsActive() +  ' years.');
                } catch (ex) {
                    console.log(ex);
                }
            }
        });
        
    }
});

var server = app.listen(80, '127.0.0.1');

What happens is that MongoDB doesn’t store the yearsActive function nor the constructor function. What MongoDB stores are just the non-function values. The result is that when we retrieve our object it will no longer be an Artist object, but just an object that just so happens to have the same properties as an Artist.

This is where Mongoose comes to the rescue! Mongoose adds a schema to your MongoDB objects. Let’s see how that works.

To add Mongoose to your project you can install it using npm install mongoose.

So first we can use mongoose.connect to get a connection to the database.

var app = require('express')();
var mongoose = require('mongoose');

var url = 'mongodb://localhost:27017/local';
mongoose.connect(url);
var db = mongoose.connection;
db.on('error', function (err) {
    console.log(err);
});
db.once('open', function (callback) {
    // ...
});

var server = app.listen(80, '127.0.0.1');

After that we can define a schema using the Schema function.

db.once('open', function (callback) {
    var artistSchema = mongoose.Schema({
        name: String,
        activeFrom: Number,
        activeTo: Number
    });
    artistSchema.methods.yearsActive = function () {
        var self = this;
        if (self.activeTo) {
            return self.activeTo - self.activeFrom;
        } else {
            return new Date().getFullYear() - self.activeFrom;
        }
    };
});

And as you can see I’ve appended the yearsActive function to the artistSchema.methods object. After that we can create a Model using mongoose.model.

var Artist = mongoose.model('Artist', artistSchema);

And after that the Artist variable (a Model) is actually the portal to your collection. It’s also a constructor function for artists. So let’s create our Massive Attack artist.

var massiveAttack = new Artist({ name: 'Massive Attack', activeFrom: 1988 });
console.log('\n\n' + massiveAttack.name + ' has been active for ' + massiveAttack.yearsActive() + ' years.');

And then we can save it using the save function.

massiveAttack.save(function (err, result) {
    if (err) {
        console.log(err);
    } else {
        // ...
    }
});

And now that the artist is saved let’s retrieve it and call that yearsActive function again. We can simply retrieve our object using Model.findOne.

Artist.findOne({ name: massiveAttack.name }, function (err, result) {
    if (err) {
        console.log(err);
    } else {
        try {
            console.log('\n\n' + result.name + ' has been active for ' + result.yearsActive() +  ' years.');
        } catch (ex) {
            console.log(ex);
        }
    }
});

And here I’ve put the findOne directly in the callback function of save, which I didn’t do before. I needed this because calling findOne directly after save didn’t yield any results (timing issue I guess). More importantly it did successfully execute the yearsActive function!

And like with the regular MongoDB driver we can use find, remove, findOneAndRemove and findOneAndUpdate.

So we’ve looked at the MongoDB driver and at the problem of schemaless objects which Mongoose fixes. I can recommend practicing a bit, as it’s really very easy to drop, create, insert, update, read and remove data, and reading the API documentation of both. We’ve only scratched the surface here, but it got you on your way.

And of course I’m going to recommend some additional reading. The Node.js Succinctly book is just a great resource for Node.js in general and it has a tiny bit on MongoDB and SQLite as well. I can also recommend MongoDB Succinctly. And Getting MEAN from Manning even has a chapter on MongoDB and Mongoose.

Happy coding!

MEAN web development #1: MEAN, the what and why

Yes, a new blog post and a new series! I apologize for not writing a post last week, I was a bit busy. I’ll try to make it up to you by starting an awesome series on MEAN web development.
I’ve been tweeting on MEAN and related technologies on Twitter, so be sure to follow me @sanderrossel as well.

But what is MEAN and why would you want to know and use it? That’s what we’ll look at in this first episode. We’ll also set up our environment. In the following posts we’ll look at each technology involved with MEAN in more detail.

  1. MEAN web development #1: MEAN, the what and why
  2. MEAN web development #2: Node.js in the back
  3. MEAN web development #3: More Node.js
  4. MEAN web development #4: All aboard the Node.js Express!
  5. MEAN web development #5: Jade and Express
  6. MEAN web development #6: AngularJS in the front
  7. MEAN web development #7: MongoDB and Mongoose
  8. MEAN web development #8: Sockets will rock your socks!
  9. MEAN web development #9: Some last remarks

 The what

So what is MEAN? I could call you dumb for not knowing, that would be mean (and unjustified, because you’ll know within seconds), but that’s not quite the mean I’m talking about! MEAN is actually an acronym (because we love acronyms in IT) and it stands for MongoDB, Express, AngularJS and Node.js. Chances are you’ve heard of those and if you read a previous blog post of mine, Web development #8: Where to go from here, you even know a little bit about what they are (although you could’ve got that from other sources too, of course).
In short, MongoDB is a NoSQL Document Model database, Node.js is a platform that allows you to run JavaScript on/as your web server, Express is a library that simplifies working with Node.js and AngularJS is a front end framework that let’s you create Single Page Applications (SPAs).

Don’t worry, we’ll look at all of them in much more detail later. In fact, I’ve already written on MongoDB in an earlier blog post, A first look at NoSQL and MongoDB in particular. Actually I’m going to ask you to read that post in a little bit.

So here’s the deal, MongoDB is a database that doesn’t use SQL, but JavaScript, as a query language, Node.js is a platform that let’s you use JavaScript on your back end, AngularJS is a JavaScript library for your front end and Express is just a library for Node.js. So that’s JavaScript across your entire stack! That’s pretty awesome, especially when you’re a fan of JavaScript.

You’re probably going to use more than just MEAN. MEAN is just a starting point, but, of course, you’re free to add (or remove) whatever you like. Perhaps a little jQuery UI, a HTML generator like Jade,  or sockets.io, a library for working with sockets in Node.js.

The why

So why would you use MEAN over other technologies? Here’s the thing, I’m not religious about any technology and you can probably do anything you can do with MEAN with other technologies as well. SQL Server and C# would do nicely, especially when throwing in SignalR, but then of course you’d have SQL in your database, C# on your back end and JavaScript in your browser. So just being able to stick with one language (unfortunately that language is JavaScript) could be considered a pro.

Let’s look at why you’d want to use any of the MEAN letters seperately.
MongoDB is a very flexible database that looks a little like the relational databases you already know. MongoDB is schemaless though, so adding any field becomes a breeze (no production downtime!). That’s especially neat when you have huge tables with lots of data. I know adding a field to any SQL database can be quite a challenge on big tables, because your entire table has to be updated. On top of that MongoDB scales well, much better than most SQL databases. Actually let’s stop on why you’d want to use MongoDB, just read my NoSQL and MongoDB article, A first look at NoSQL and MongoDB in particular.

Node.js is really an alternative to popular web servers such as Apache or IIS (Internet Information Services). So how is Node.js different than those two (and others)? Well, Apache and IIS both listen to incoming HTTP requests using threads. So that means a number of different little ‘processes’ (the threads) are listening for incoming requests and handle them. That means that if all threads are busy no new requests can be handled at that time and your server response becomes slower.
Node.js, in contrast, uses only a single thread to listen for incoming HTTP requests. What it does is listen for an incoming request, put it on a stack, and handle it on a different thread. This process is so fast (if you do it right) that Node.js should be able to handle more concurrent connections than Apache or IIS. Of course if you mess up in Node.js you’ll be blocking the server for everyone else too.
And if you’re going to use Node.js you’re probably going to use Express as well as it really makes Node.js development easier (but you’re entirely free to do a little ‘MAN’ development, of course 🙂 ).

And why would you want to use AngularJS? AngularJS is a framework for creating Single Page Applications. On ‘traditional’ web pages your page needs to refresh entirely for each server request. So imagine you’re at some web shop and you’re reading product reviews. There’s ten reviews per page and you’ve just read the tenth. When you click on ‘next page’ the entire page gets refreshed. So the server sends the entire HTML, the product images (if they’re not cached by your browser), the product description, other recommended products, etc. to your browser. That’s a whole lot of information you already had! In a SPA you’d only send the ten new product reviews and replace the old ones with the new ones in your browser (for example using jQuery, or AngularJS).
So a SPA, when done well, is a lot faster and better usable than a traditional application. Of course you may use jQuery for AJAX requests and DOM manipulation, but AngularJS is a framework that was kind of built to handle these exact cases, whereas jQuery is more general. So AngularJS could be a good choice when building SPAs. Of course you can replace AngularJS with another framework if you like, perhaps Ember.js or Backbone.js, you could be doing MEEN or MEBN development (I’m really just making that up, but why not, right?).

So put that together and MEAN is just an all-JavaScript stack that’s fast, responsive and flexible. Did I mention it’s all open source, so free to use? That’s pretty awesome!

Setting up your environment

MongoDB

Let’s get to work, shall we? Let’s start with setting up MongoDB. As I mentioned I’ve already written on MongoDB in a previous post, A first look at NoSQL and MongoDB in particular. As luck has it I’ve also described how to set up MongoDB, so I suggest you read that post and especially the “Getting started with MongoDB” bit (you can skip the C# part). Little has changed since I wrote that post some months ago, but I’ll briefly discuss the differences. You can download MongoDB from the downloads page. The default install path has changed to “C:\Program Files\MongoDB\Server\3.0\bin”. You can run MongoDB through the command line or by running mongod.exe directly.
You should also install MongoVUE, as described in the blog post. I’ll be using it for this series anyway. When first starting MongoVUE you need to specify a connection. Give it any name you like, set ‘localhost’ as server and you’re good to go. Other than that I think MongoVUE is pretty self explanatory, especially when you’ve used SQL Server.

Node.js

So let’s set up Node.js next. Head over to nodejs.org and click the big green install button. It should give you the installer for your system (I’m assuming you’re on a Windows machine). You can, of course, also select an installer manually by heading over to the downloads page. Then just run the installer and make sure you also install the npm package manager. Actually, just install everything. Once it’s installed you can run any Node.js application (which is really just a JavaScript, or .js, file) from the command prompt. And while we’re on the subject I want to coin a new term CPDD, Command Prompt Driven Development (ok, that was a joke). Why are we still using command prompts in 2015!? So I’m not a fan of command prompts because it’s a lot of typing and I always forget what to type. If you’re like me, no worries, I’ve got you covered!

So while we’re at it let’s create a very simple hello world! We’ll see Node.js in action and we’ll be able to fire it up using the command prompt. So first we’ll create a folder for our ‘project’. I’ve put it in C:\dev\hellonode\ and there I’ve created a file called hellonode.js. Now put the following code in that file.

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello, Node.js!');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

As you can see it’s just JavaScript. The example was taken from the Node.js homepage. So we first create an instance of the http module by invoking the require function and pass in the string (id) ‘http’. When we have our http object we invoke the createServer function and pass in a function as only parameter. The function has a request (the HTTP request) and a response as parameters. So whenever the server receives an HTTP request this function is called and we can inspect the method (GET, POST etc.) and any parameters and basically anything that was sent with the request. We’re not really interested in any of that here though since we’re just going to send the same result every time a request is made. We write HTTP code 200 (OK) and the content type text to the result header and we end the request by invoking the end function and passing it the text ‘Hello, Node.js!’.
The function createServer returns a Server object. We invoke listen on this Server object, pass in a port and IP address (localhost in the example) and at that point our server goes up and running and listens for requests.

Don’t worry if you didn’t get that. We’ll look at Node.js in much more detail in a later post. So now to get this running. Open up a command prompt and type in the following (excluding double quotes “”): “node C:\dev\hellonode\hellonode.js” and you should see that your server is running. Now browse to localhost:1337 and you should see “Hello, Node.js!” in your browser window.
Congrats, you just created your first Node.js app!

Express and npm

So next we need to install Express. We’ll do this using npm. npm is a JavaScript package manager and it’s the default package manager for Node.js. There are alternatives, like Bower, but let’s just stick to npm. So open up another command prompt (argh!). First we want to make sure npm is on the latest version. We can issue an update command with the following command “npm install npm -g”. After that move to the folder that holds your project using command “cd C:\dev\hellonode” and then use the command “npm install express” to actually install Express to your project. To uninstall express you can use the command “npm uninstall express”.
Alternatively you can create a small file called package.json and put the following JSON in it.

{
  "name": "hellonode",
  "version": "1.0.0"
}

Now when installing or uninstalling a package add –save at the end of your command, like so “npm install express –save” and “npm uninstall express –save” and npm will keep track of dependencies in this file. For example when installing Express your packages.json file will look as follows.

{
  "name": "hellonode",
  "version": "1.0.0",
  "dependencies": {
    "express": "^4.12.3"
  }
}

So to make sure it really works you can create a JavaScript file called helloexpress.js and try out the Hello world example from the Express “Hello World” example page. Try it out by running the following command from a command prompt: “node C:\devhellonode\helloexpress.js” and browsing to localhost:3000.

So that’s it! We’ve got a little bird’s eye view on MEAN and we’ve got both MongoDB and Node.js up and running and we’ve installed Express using npm. I’m not discussing AngularJS here because we’ve seen how to add front end libraries to our pages in previous blog posts, for example Web development #6: Getting interactive with JavaScript. We’ll get to setting up AngularJS anyway when I post about it.

In next posts we’ll look at MongoDB, Node.js, Express and AngularJS in much more detail and we’ll see how they work together.
In the meantime, if you’re interested in knowing more about any of those I can really recommend the free ebooks by Syncfusion (yeah, here we go again). They have books on all the MEAN parts, MongoDB Succinctly, Node.js Succinctly and AngularJS succinctly.  You have to sign up, but it’s free and really worth it.
If you really want to get into it I can recommend some books by Manning Publications. They have books on all the seperate technologies, but they also have an upcoming book on the entire MEAN stack, Getting MEAN with Mongo, Express, Angular, and Node.
I’m looking forward to reading your comments and I hope to see you back with the next installment.

Stay tuned!

A first look at NoSQL and MongoDB in particular

So today I decided to have a look at NoSQL. It’s not exactly new and actually I’m a bit late to jump on the NoSQL train, but so far I had no need for it (and actually I still don’t, but I had some time to spare and a blog to write). Since NoSQL can be quite complicated, as it imposes a new way of thinking about storing data, and I can’t possibly discuss everything there is to discuss, I’ll add some additional reading at the end of the article.

An overview of NoSQL

First things first, what is NoSQL? As the name implies it’s not SQL (Structured Query Language), a standard for databases to support the relational database model. As SQL has been the standard for about thirty to twenty years I’m not going to discuss it, you probably know it. A common misunderstanding with NoSQL is that it stands for “no SQL”, while it actually means “Not Only SQL”, which implies there is at least some SQL-y goodness to be had in NoSQL as well. Whatever that SQL-y goodness may be it’s not the relational model. And this is where NoSQL is fundamentally different from SQL, expect de-normalized and duplicated data. This ‘feature’ makes it possible to make schema’s flexible though. In NoSQL it’s generally easy to add fields to your database. Where in a SQL database you would possibly lock a table for minutes if it contains a bit of data, in NoSQL you can add fields on the fly (during production!). Querying data can also go faster than your typical SQL database, because of the de-normalization you reduce or even eliminate expensive joins. A downside to this method of storing data is that is it harder to get consistency in your data. Where in SQL consistency is more or less guaranteed if you have normalized your database NoSQL offers consistency or eventual consistency. How NoSQL databases provide this (eventual) consistency differs per vendor, but it doesn’t come as natural as in SQL databases. Also, because of the way data is stored and queried NoSQL databases tend to scale better across machines than SQL databases.
Other than that no uniform definition can be given for NoSQL because there is no standard. Still NoSQL can be roughly divided into four database models (some would say more, let’s not get into such details): Document, Graph, Key-value and Wide Column. So let’s get a quick overview of those and try one out!

The Document Model

First there’s the Document model. When thinking of a document don’t think of a Word or Excel document, think of an object like you would have in an object-oriënted language such as Java or C#. Each document has fields containing a value such as a string, a date, another document or an array of values. The schema of a document is dynamic and as such it’s a breeze to add new fields. Documents can be queried on any field.
Because a value can be another document or array of documents data access is simplified and it reduces or even eliminates the use for joins, like you would need in a relational database. It also means you will need to de-normalize and store redundant data though!
Document model databases can be used in a variety of applications. The model is flexible and documents have rich query capabilities. Additionally the document structure closely resembles objects in modern programming languages.
Some examples of Document databases are MongoDB and CouchDB

The Graph Model

Next there’s the Graph model. This model, like its name implies, stores data in graphs, with nodes, edges and properties to represent the data. A graph is a mathematical structure and I won’t won’t go into it any further. Graph databases model data as networks of relationships between entities. Sounds difficult? I think so too. Anyway, when your application is based on various relationships, such as social networks, the graph database is the way to go.
Some examples of Graph databases are HyperGraphDB and Neo4j.

The Key-value Model

Key-value databases are the simplest of the NoSQL databases. They basically provide a key and a value, where the value can be anything. Data can be queried by key only. Each key can have a different (type of) value. Because of this simplicity these databases tend to be highly performant and scalable, however, because of this simplicity, they’re also not applicable to many applications.
Some examples of Key-value databases are Redis and Riak.

The Wide Column Model

Last is the Wide Column model. Like the Key-value model the Wide Column model consists of a key on which data can be queried, can be highly performant and isn’t for each application. Each key holds a ‘single’ value that can have a variable number of columns. Each column can nest other columns. Columns can be grouped into a family and each column can be part of multiple column families. Like the Object model the schema of a Wide Column store is flexible. Phew, and I though the Graph model was complicated!
Some examples of Wide Column databases are Cassandra and HBase.

Getting started with MongoDB

So anyway, there you have it. I must admit I haven’t actually used any of them, but I’m certainly planning to get into them a bit deeper. And actually, as promised, I’m going to try one out right now! I’ve picked MongoDB, one of the fastest growing databases of the moment. It’s a Document store and so has a wider applicability than the other types. You can download the free version at www.mongodb.org. There’s also a lot of documentation on there, so I recommend you look around a bit later. Installation is pretty straightforward. Just click next a few times and install. If you change any settings I won’t be held responsible if it doesn’t work or if you can’t follow the rest of this post. So go ahead, I’ll wait.
Ready? Once you have installed MongoDB you’ll need to run it. I was a bit surprised it doesn’t run as a service (like, for example, SQL Server) by default.
So how do you start MongoDB? Open up a command window (yes, really). First you need to create the data directory where MongoDB stores its files. The default is data\db, to create it type md data\db in your command window. Next you need to navigate to the folder where you’ve installed MongoDB. For me this was C:\Program Files\MongoDB 2.6 Standard\bin. Then start mongod.exe. If, like me, you’ve never had to work with a command window here’s what you need to type in your command window:

cd C:\
md data\db
cd C:\Program Files\MongoDB 2.6 Standard\bin
mongod.exe

If you still encounter problems or you’re not running Windows you can check this Install MongoDB tutorial. It also explains how to run MongoDB as a service, so recommended reading material there!

You might be wondering if MongoDB has a Management System where we can query and edit data without the need of a programming language. You can use the command window to issue JavaScript commands to your MongoDB database. To do this you’ll need to start mongo.exe through a command window. The Getting Started with MongoDB page explains this in greater detail. However I would HIGHLY RECOMMEND that you download MongoVUE instead. It’s an easy to use, graphical, management system for MongoDB. Do yourself a favour and install it before you read any further. You can check out the data we’ll be inserting and editing in the next paragraphs.

One more thing before we continue. Mongo stores its documents as BSON, which stands for Binary JSON. It’s not really relevant right now, but it’s good to know. We’ll see some classes named Bson*, now you know where it comes from. MongoVUE let’s you see your stored documents in JSON format.

The C# side of MongoDB

So now that we are running MongoDB start up a new C# Console project in Visual Studio. Make sure you have saved your project (just call it MongoDBTest or something). Now open up the Package Manager Console, which can be found in the menu under Tools -> Library Package Manager -> Package Manager Console. Getting MongoDB to work in your project is as simple as entering the following command: PM> Install-Package mongocsharpdriver. The MongoDB drivers will be installed and added to your project automatically. Make sure you import the following namespaces to your file:

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Driver.Linq;
using System;
using System.Linq;

So are you ready to write some code? First we’ll need something we want to store in our database, let’s say a Person. I’ve created the following class to work with when we start.

public class Person
{
    public ObjectId Id { get; set; }
    public string Name { get; set; }
}

Classes don’t come easier. Notice I’ve used the ObjectId for the Id field. Using this type for an ID field makes Mongo generate an ID for you. You can use any type as an ID field, but you’ll need to set it to a unique value yourself (or you’ll overwrite the record that already has that ID).  Another gotcha is that you need to call your ID field Id (case-sensitive) or annotate it with the BsonIdAttribute. And since we’re talking about Attributes, here’s another one that’ll come in handy soon, the BsonIgnoreAttribute. Properties with that Attribute won’t be persisted to the store.

public class Person
{
    [BsonId()]
    public ObjectId MyID { get; set; }
    public string Name { get; set; }
    [BsonIgnore()]
    public string NotPersisted { get; set; }
}

For now we’ll work with the default Id field. So now let’s make a connection to our instance and create a database. This is actually rather easy as you’ll see. Mongo creates a database automatically whenever you put some data in it. After we got a connection to our database we’ll want to put some data in that database. More specific, we want to create a Person and store it. To do this we’ll first ask for a collection of Persons with a specific name (a table name, if you like). You can store multiple collections of Persons if you use different names for the collections, so beware for typo’s! After we got a collection from the database we’ll create a Person and save it to the database. That’s a lot of stuff all at once, but actually the code is so simple you’ll get it anyway!

// Connect to the database.
string connectionString = "mongodb://localhost";
MongoClient client = new MongoClient(connectionString);
MongoServer server = client.GetServer();
MongoDatabase database = server.GetDatabase("testdb");

// Store a person.
MongoCollection persons = database.GetCollection("person");
Person p1 = new Person() { Name = "Sander" };
persons.Save(p1);
Console.WriteLine(p1.Id.ToString());
Console.ReadKey();

Wow, that was pretty easy, wasn’t it!? Mongo generated an ID for you, as you can see. Next we’re going to get this Person back from our database. There’s a few ways to do this. We can work using the Mongo API or we can use LINQ. Both present multiple methods of querying for one or multiple records. I suggest you read the documentation and experiment a bit. I’ll already show you a couple of methods to get our Person back from the database.

// Using the MongoDB API.
ObjectId id = p1.Id;
Person sanderById = persons.FindOneById(id);
Person sanderByName = persons.FindOne(Query.EQ(p => p.Name, "Sander"));

// Using LINQ.
var sandersByLinq = from p in persons.AsQueryable()
                    where p.Name == "Sander"
                    select p;
Person sander = sandersByLinq.SingleOrDefault();

You’ll notice the Query.EQ. EQ stands for equal and builds a query that tests if a field is equal to a specific value. There are other query types like GT (Greater Than), LT (Less Than), In, Exists etc.

But wait, I’m not happy with this code at all! What Person really needs are LastName and Age fields. Now here comes this flexible schema I’ve been telling you about. Simply add the properties to your class. If you’ll fetch a Person that doesn’t have these fields specified they’ll be set to a default value. In case of Age you might want to use an int? rather than an int, or your already existing Persons will have an age of 0 rather than null.

Person incompleteSander = persons.FindOne(Query.EQ(p => p.Name, "Sander"));
Console.WriteLine(String.Format("{0}'s last name is {1} and {0}'s age is {2}",
    incompleteSander.Name, incompleteSander.LastName, incompleteSander.Age.ToString()));

incompleteSander.LastName = "Rossel";
incompleteSander.Age = 27;

// Let's save those new values.
persons.Save(incompleteSander);

Console.ReadKey();
// Retrieve the person again, but this time with last name and age.
Person completeSander = persons.FindOne(Query.EQ(p => p.Name, "Sander"));
Console.WriteLine(String.Format("{0}'s last name is {1} and {0}'s age is {2}",
    completeSander.Name, completeSander.LastName, completeSander.Age.ToString()));

Console.ReadKey();

Now let’s also add an address to Person. Address will be a new class and Person will hold a reference to an Address. Now you can just model this like you always would.

public class Person
{
    public ObjectId Id { get; set; }
    public string Name { get; set; }
    public string LastName { get; set; }
    public int? Age { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string AddressLine { get; set; }
    public string PostalCode { get; set; }
}

Notice that Address doesn’t need an Id field? That’s because it’s a sub-document of Person, it doesn’t exist without a Person and as such doesn’t need an Id to make it unique. Now fetch your already existing Person from the database, check that it’s address is empty, create an address, save it and fetch it again.

Person addresslessSander = persons.FindOne(Query.EQ(p => p.Name, "Sander"));
if (addresslessSander.Address != null)
{
    Console.WriteLine(String.Format("Sander lives at {0} on postal code {1}", addresslessSander.Address.AddressLine, addresslessSander.Address.PostalCode));
}
else
{
    Console.WriteLine("Sander lives nowhere...");
}

addresslessSander.Address = new Address() { AddressLine = "Somewhere", PostalCode = "1234 AB" };
persons.Save(addresslessSander);

Person addressSander = persons.FindOne(Query.EQ(p => p.Name, "Sander"));
if (addressSander.Address != null)
{
    Console.WriteLine(String.Format("Sander lives at {0} on postal code {1}", addressSander.Address.AddressLine, addressSander.Address.PostalCode));
}
else
{
    Console.WriteLine("Sander lives nowhere...");
}

Console.ReadKey();

Make sure you check out the JSON in MongoVUE. Also try experimenting with Lists of classes. Try adding more Addresses, for example. We haven’t deleted or updated any records either, we’ve only overwritten entire entries. Experiment and read the documentation.

We’ve now scratched the surface of NoSQL and MongoDB in particular. Of course MongoDB has a lot more to offer, but I hope this post has helped getting your feet wet in NoSQL and MongoDB. Perhaps it has given you that little push you needed to get started. It has for me. Expect more NoSQL blogs in the future!

Additional reading

As promised, here’s some additional reading:
NoSQL – Wikipedia
MongoDB White Papers
Document Databases : A look at them
How to take advantage of Redis just adding it to your stack

Comments are welcome. Happy coding!