Experimenting with MongoDB from C#

I’ve often felt that we treat relational databases as a hammer to use with every kind of nail, screw, bolt, rivet, metric nut, and wall anchor we encounter in software development. The modern relational databases is a marvelous piece of engineering, and we have centuries of collective experience in designing, optimizing, securing, and managing them, but they just aren’t the best fit for every scenario.

The last few months I’ve been keeping an eye on the growing No-SQL movement. I’d like to make room for the No-SQL conference (nosqleast – their motto is: select fun, profit from real_world where relational=false;), but I’ll just have to wait for a debrief from Matt P. Here are a couple great blog posts for background on the No-SQL thing:

MongoDB I wanted to experiment with a document oriented database myself and chose MongoDB. From the FAQ:

MongoDB is an document-oriented DBMS. Think of it as a persistent object store. It is neither a relational database, nor even "table oriented" like Amazon SimpleDB or Google BigTable. If you have used object-relational mapping layers before in your programs, you will find the Mongo interface similar to use, but faster, more powerful, and less work to set up.

I chose MongoDB because it looked easy to setup and run with.

  1. Download and extract the binaries from MongoDB downloads.
  2. Create a c:\data\db directory (that’s the default storage location – you can override it)
  3. Run the MongoDB daemon – mongod.exe

To talk to MongoDB I used mongodb-csharp. You can either download the source as a zip file, or use a Git client like Git on Windows to clone the github repository. Sounds difficult, but Git is easy once you’ve adopted to the terminology, and as a bonus, it’s screaming fast. There is a Visual Studio solution included with the sources, so you can open it, build it, and out pops a MongoDB.Driver assembly.

Connecting to a database looks like this:

var mongo = new Mongo();
mongo.Connect();
var db = mongo.getDB("movieReviews");

I’m running MongoDB on the local machine and it’s listening on the default port with no special security settings. That simplifies the code, but also notice I can ask for a database (movieReviews), and if it doesn’t exist MongoDB will create the database for me. I don’t need to create tables or schemas or setup primary keys. It just works. I’m thinking document oriented databases are to relational databases what dynamic languages are to static languages.

The next step is to get/create a collection and start adding documents to it.

var movies = db.GetCollection("movies");

var movie = new Document();
movie["title"] = "Star Wars";
movie["releaseDate"] = DateTime.Now;
movies.Insert(movie);

A collection is somewhat analogous to a table in the RDBMS world, but instead of rows and columns a collection is a bunch of documents that internally are stored in a binary JSON format (BSON). The documents can contain anything – they are schemaless, but MongoDB understands how to index and query the documents.

var spec = new Document();
spec["title"] = "Star Wars";
var starWars = movies.FindOne(spec);

With a few more abstractions (and a little bit of LINQ), document oriented databases could be a huge hit in .NET. Although, they might be better aligned with a language that runs on the DLR…

Print | posted @ Wednesday, October 14, 2009 9:12 PM

Comments on this entry:

Gravatar # re
by Jack at 10/15/2009 4:53 AM

nice, I like it very much!
  
Gravatar # re: Experimenting with MongoDB from C#
by Mike Borozdin at 10/15/2009 7:54 AM

What about relationships between entities? How are they handled?
  
Gravatar # re: Experimenting with MongoDB from C#
by dm at 10/15/2009 8:07 AM

@mike it is possible to have a reference from one object/document to another - although generally this will require an additional client/server turnaround to "traverse". so you can do it but the typical way to use mongodb is to design a schema where the number of references between objects is not too high.

one way to do that is to embed objects within others. you can nest objects and arrays of objects which then has all the data one typically needs together in the first place. see "reaching into objects" and "schema design" pages on the mongodb.org site...
  
Gravatar # re: Experimenting with MongoDB from C#
by developingchris at 10/15/2009 9:31 AM

At pyohio, one of the engineers from SourceForge, presented on the fact that they are completely running on MongoDB now. He showed benchmarks for mySql, mongo, couch and 6 other ones that I don't have notes on. The short story is that mongo out performed all of them by hundreds of percent of transactions . It even seemed to scale much closer to linear on inserts when approaching 1 million documents in the db.
  
Gravatar # re: Experimenting with MongoDB from C#
by Sam Corder at 10/15/2009 10:45 AM

Hey thanks for the nice write up. A lot of times when I'm working with the driver I like to use the default item methods so I can shorten the code a bit. Also Document has an Append method that returns itself so that you can chain it. You can squash your movies example down to one line.

db["movies"].Insert(new Document().Append("title", "Star Wars").Append("releaseDate", DateTime.Now);

In practice that might not look so pretty but it makes sending a query a little easier.

var cursor = db["movies"].FindOne(new Document().Append("title", "Star Wars"));

As for Linq support, I recently merged in a contribution. There aren't any binaries up yet but compiling from source should work fine.
  
Gravatar # re: Experimenting with MongoDB from C#
by scott at 10/15/2009 10:59 AM

@Sam: Excellent, thanks for the tips!
  
Gravatar # Experimenting with MongoDB from C#
by AspNetSpy at 10/15/2009 11:22 AM

This post has been spied by AspNetSpy.com
  
Gravatar # re: Experimenting with MongoDB from C#
by Arne Claassen at 10/15/2009 11:47 AM

If you want to get some examples of how the (albeit basic) Linq support Sam mentioned works, I wrote up a post on the contrib here: www.claassen.net/...
  
Gravatar # Nice post
by Dave at 10/19/2009 8:16 AM

This seems to work well,

However I am having trouble trying to deserialize an object using JSON.NET

Movie m = JsonConvert.DeserializeObject<Movie>(starWars.ToString());

public class Movie
{
public Oid _id { get; set; }
public string title {get;set;}
public DateTime releaseDate { get; set; }

}

What is the Trick?
  
Gravatar # Nice post
by Dave at 10/19/2009 8:16 AM

This seems to work well,

However I am having trouble trying to deserialize an object using JSON.NET

Movie m = JsonConvert.DeserializeObject<Movie>(starWars.ToString());

public class Movie
{
public Oid _id { get; set; }
public string title {get;set;}
public DateTime releaseDate { get; set; }

}

What is the Trick?
  
Gravatar # re: Experimenting with MongoDB from C#
by Cedric at 12/7/2009 2:44 AM

HOw would these databases handle ,temporal data
  
Gravatar # re: Experimenting with MongoDB from C#
by kellyb at 2/2/2010 5:12 PM

Do you know of any Windows base web hosting providers that offer MongoDB support?
  
Gravatar # re: Experimenting with MongoDB from C#
by Daniel Wertheim at 2/5/2010 9:32 AM

Nice article.

I have written some examples of how to use Json.Net to get the mappings to work as well as how to use Castle Dynamic proxy to take care of the mappings.

daniel.wertheim.se/...

//Daniel
  
Gravatar # re: Experimenting with MongoDB from C#
by Daniel Wertheim at 2/12/2010 2:33 AM

Nice to know...
Samus has fixed the issue with the Oid.ToString implementation in the MongoDb-driver, so it shall now give correct json. I don't know if it has reached the master-version yet.

I made a follow up to my initial post, where I just did some refac. to show how it could be used.

daniel.wertheim.se/...

//Daniel
  

Your comment:

Title:
Name:
Email:
Website:
 
Italic Underline Blockquote Hyperlink
 
 
Please add 8 and 7 and type the answer here: