Joe Doyle's Coding Blog

Getting Started With MongoDB and C# Revisited

A few years ago I wrote about using the MongoDB driver in C#. Its been one of my most popular posts and it really needs an update! Since 2011, the 10gen driver has become the standard. Its been getting updated on a regular basis with features that bring it inline with what we would expect in C#. I've been using MongoDB for all of my personal projects and have been very happy with it. So here's an update for what it looks like today to use the MongoDB driver version 1.8.1.

Getting the Driver

The source is still located on GitHub at https://github.com/mongodb/mongo-csharp-driver. But now that we have NuGet, the easiest way to get started is by using the NuGet package mongocsharpdriver (http://nuget.org/packages/mongocsharpdriver/). It's everything we need compiled and ready to go.

To the Code

The best place to get started is still the official 10gen C# driver tutorial at http://www.mongodb.org/display/DOCS/CSharp+Driver+Tutorial. It covers what you need to get started and helps to keep track of what is new each release.

I'm going to stick with the original app which was a simple tool that keeps track of passwords and various notes. I've been using it for a few years and have been happy with it's simplicity.

The first change is how we connect. It used to look like this:

MongoServer server = MongoServer.Create("mongodb://myserver");  
MongoDatabase db = server.GetDatabase("TheDatabase");  

That style has been deprecated and instead we should use the new MongoClient class. Here's what that looks like now:

var mongoClient = new MongoClient("mongodb://myserver");  
mongoServer = mongoClient.GetServer();  
var database = mongoServer.GetDatabase("TheDatabase");  

Not too different, but the naming is definitely clearer. It no longer looks like we're creating a server which is nice.

Getting a reference to the collection is still the same. We specify our CredentialSet class when we get our collection so that we don't need to work with BsonDocuments if we don't want to. Even though MongoDB is a schema-less document store, it does make life easier to have a fixed type to work with.

var passwords = database.GetCollection<CredentialSet>("passwords");  

And just as a reminder, our model looks like this:

public class CredentialSet  
{
    public ObjectId Id { get; set; }
    public string Title { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
    public string WebSite { get; set; }
    public string Notes { get; set; }
    public int Owner { get; set; }
    public DateTime LastUpdate { get; set; }
}

One thing that did get fixed is the _id issue from last time. The driver will now use Id as the document id automatically. It also will look for _id, but that's not inline with C# standards.

So lets save a new document:

var password = new CredentialSet();

// set the property values.
passwords.Save(password);  

Now that we have a saved document, let's query for it. Here's where we get to my favorite new feature; support for Linq.

Instead of building up a Query object and using Find or FindAll, we can access our collection as an IQueryable and use Linq against it. Like most custom Linq providers, not every operation is supported, but its typically nothing that can't be worked around.

So before we had:

var query = Query.EQ("Title", "A password");  
var oneDocument = passwords.FindOne(query);  

Now we can do:

var result = passwords.AsQueryable().SingleOrDefault(x => x.Title=="A password");  

Of course the older methods are still available for the operations that don't make sense with Linq, such as map/reduce.

Next Time: Aggregation Framework, V8, and Full Text Search

Another nice feature in MongoDB 2.1 and later is the Aggregation Framework. It provides an easier alternative to map/reduce. I'm still learning about it, but I am using it on this site to generate some statistics for my dashboard view. As of 2.4, V8 now powers MongoDB and we get a few extra benefits such as multiple scripts executing at the same time. We also got the first version of a full text search engine built into MongoDB. I'll dive into these next time.