Be honest now: did you perform any form of analysis before deciding on using a relational database for your current project? Probably not. Sure, you need some form of persistent storage – but a RDBMS? Probably not. I’ll leave it to Greg Young and Rob Conery to convince you why you’d want to consider other options – in this post I’d like to give you a gentle introduction to getting up and running with MongoDB.
MongoDB?
“MongoDB (from "humongous") is a scalable, high-performance, open source, schema-free, document-oriented database.”
Go download MongoDB and unzip it somewhere. Next, create a folder called data on your root c drive – this is where MongoDB will persist stuff to (you can override the location via its config, but lets keep things simple for this demo).
Next, fire up the MongoDB daemon by executing the mongod.exe file. That’s it! Database installed and ready to be used. Bit less pain than that SQL Server setup wizard, no?
NoRM
In order to access our MongoDB instance from a .NET project, we’ll need some sort of connector. Some really cool guys led by Andrew Theken have created just that, called NoRM. You’ll need to go to the projects github repository, download the source code (click the “Download Source” button, top left) and compile it yourself – but you can handle that, right? Cool. Once you’ve done that, fetch the norm.dll file from the bin folder.
Create yourself a new project in Visual Studio and reference the norm.dll file. Now we’re all set! The cool thing about MongoDB is that we don’t need to define no database or schema or whatever first, we can just start chucking objects into it. But first, we need some classes. Create yourself a simple domain model to run some tests with – or just copy/paste mine:
public class Person
{
[MongoIdentifier]
public SocialSecurityNumber SocialSecurityNumber { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public Gender Gender { get; set; }
public override int GetHashCode()
{
return SocialSecurityNumber.GetHashCode();
}
}
public class SocialSecurityNumber
{
public string Number { get; set; }
public override int GetHashCode()
{
return Number.GetHashCode();
}
}
public enum Gender
{
Male,
Female
}
Notice the MongoIdentifier attribute – the only reason I needed this was because I wanted to use a natural primary key (and notice that the type of my key is in fact a complex object itself). If you have an property called ID which is either a Guid or ObjectID, then NoRM will automatically pick this up.
Right, time to execute some code. Let’s add a few persons to our database:
[TestFixture]
public class Adding_Persons_to_database
{
[Test]
public void Can_add_persons_to_database()
{
// create a provider. "testdb" is the name of our db -
// it gets created automatically if it doesn't exist yet
var provider = new MongoQueryProvider("testdb");
// let's make sure there are no Persons in the db
provider.DB.DropCollection(typeof(Person).Name);
var ben = new Person
{
Age = 27,
Gender = Gender.Male,
Name = "Ben",
SocialSecurityNumber = new SocialSecurityNumber {Number = "1"}
};
var bob = new Person
{
Age = 12,
Gender = Gender.Male,
Name = "Bob",
SocialSecurityNumber = new SocialSecurityNumber { Number = "2" }
};
// this is where we insert into the db
provider.DB.GetCollection<Person>().Insert(ben);
provider.DB.GetCollection<Person>().Insert(bob);
// this is how we query the db
var NumberOfPersons = new MongoQuery<Person>(provider).Count();
Assert.That(NumberOfPersons, Is.EqualTo(2));
}
}
Okay, so this was a fairly primitive example. But look at what’s not here: no database to set up, no table schemas to define, no object-to-relational mapping to configure. This is just plug and play persistence, pure and simple. Sure, there are limitations and weaknesses and trade-offs to be considered when comparing an object/document DB to a relational DB, and the NoRM API is pretty infantile yet - but the whole NoSQL thing is something that beggs further investigation in my opinion because on the surface it looks pretty damn cool.