NoRM: A fantastic friction-free interface to MongoDB
Posted by Andrew Theken on May 23, 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 http://groups.google.com/group/norm-mongodb.
- 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: http://github.com/atheken/NoRM/zipball/v0.9.0,
- Project Page (the master branch will always “Stable”): http://github.com/atheken/norm.
Remember that we want NoRM to be the best C# driver for MongoDB possible, so please give us feedback, either in the Google Group or follow me on twitter (@atheken).
Cheers.
Jim Wooley said
Thanks for the work on the MongoDb LINQ implementation. I did notice that there are some bugs when parsing the expression strings from VB clients. This is typically caused by differences in the expression trees, particularly with string comparisons (The method “CompareString” is not supported in QueryTranslator.VisitMethodCall). If you would like, I can contribute the test library in VB and possible help to resolve the issues that arise.
Andrew Theken said
Hi Jim, I would definitely recommend forking my repo on github and getting it working in there. I would also suggest sending the idea to the google group to measure their enthusiasm. Adam Schroder (http://schotime.net/blog/index.php) really has owned the LINQ provider for the last month or two, so I would like to get his opinion on it — he reads the group pretty regularly, so posting there will probably be the best.
NoRM: A fantastic friction-free interface to MongoDB « Andrew Theken’s C# Blog | Head.SmackOnTable(); said
[...] NoRM: A fantastic friction-free interface to MongoDB « Andrew Theken’s C# Blog. Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages. [...]