NoRM: A fantastic friction-free interface to MongoDB

23 May 2010

As promised in my previous post, I am going to introduce you to a project that I’ve been working on with a great team of people on GitHub. NoRM is a .net library to interact with the document-oriented database MongoDB. We set about doing this in a way that makes sense for the C# developer who doesn’t want to spend an inordinate amount of time configuring the database. As you’ll see in a moment, with NoRM, there’s very little you need to do to get started with MongoDB. NoRM stands for “No Object-Relational Mapping” - it seems that people are concerned about leaving relational databases because they’ll lose the low-friction environments they’ve come to expect (think ‘LINQ-to-SQL’). Another concern around moving to a NoSQL option is the notion that these datastores carry little or no structure. By creating a strongly-typed interface to MongoDB, I feel that we have addressed both of these concerns. So, just to whet your appetite, here’s an example of how you’d use NoRM to store some widgets.

//First, define your document (this can be very similar to your concept of "Model"
// notice there''s no special attributes or configuration.)
public class Widget
{
	public ObjectId Id {get;set;}
	public String Color {get;set;}
	public double Price {get;set;}
	public DateTime ReleaseDate {get;set;}
	public IEnumerable Reviews {get;set;}
}

//Next, spool up a connection to your database 
//(The DB doesn''t have to exist yet, but MongoDB DOES need to be running)
using(var db = Mongo.Create("mongo://localhost/ProductDB")
{
	//Get a reference to the collection in which we want to 
	//store our Widgets (doesn''t have to exist yet.)
	var widgets = db.GetCollection();

	//create a widget instance.
	var topSellingWidget = new Widget{ Id = ObjectId.NewObjectId(), 
		Color = "Red", Price = 39.95,
	ReleaseDate = DateTime.Now, Reviews = Enumerable.Empty() };

	//now, save the instance
	widgets.Save(topSellingWidget);

	//lastly, retrieve it from the DB.
	var hydratedTopSellingWidgetFromDB = widgets.FindOne(new {Color = "Red",
		Price = 39.95});
}

That’s just a taste of the simplicity that is NoRM, there’s a huge amount of functionality that I’m not covering including:

  • Fluent configuration
  • Solid LINQ support
  • Advanced update capabilities (update single or multiple documents that match template documents)
  • Map/Reduce functionality.
  • Support for MongoDB operators via the “Q” (Qualifiers) and “M” (Modifiers) classes.
  • If you need it, “Weakly-typed” interaction via the “Expando” class.
  • Bulk-insert capability (a la SqlBulkCopy)

Aside from actual “features”, there are lots of elements that make software good, here’s a few things I think make NoRM awesome: Tests: We have more than 400 tests that verify the functionality found in NoRM, and although we have just reached the v0.9.0 milestone, the library is very stable, and I am aware of production deployments using NoRM, today.

Participation: I started NoRM in the last few days of January 2010, and have seen incredible participation from the Open Source community - I’ve learned a lot about what people do — and don’t — need in a library, and some of the interesting pieces of helping to shape an Open Source project (hopefully I can share that in another blog post). We have a vibrant community at Google Groups. Pragmatism and Experience: I am routinely impressed by the ideas and code that the project’s contributors bring forward.

Please download and use the library: Stable Milestone Project Page the master branch will always “Stable”. Remember that we want NoRM to be the best C# driver for MongoDB possible, so please give us feedback, either in theGoogle Group or follow me on twitter (@atheken).

Cheers.