Wednesday, March 9, 2011

Developer's notes on Mongo database

I like playing with new technologies and NoSQL and MongoDB is not an exception.
But, while working with Mongo, I have made few mistakes, that turned out to be painful to me.

1. Do not allow MongoDriver classes go beyond your DAL

Firstly, I neglected layered structure, planning my DAL for building fresh project on mongo. The original thought, was to create factory-class that will contain accessors for all mongo collections, of the application. Of course these collections were implemented with help of C# mongo driver (using MongoCollection class). That solution, soon stroked me in the back, since MongoCollection methods, provoke usage of hard-coded literals for complex queries.
After a while, a whole application were filled with a lot's of magic-strings with field names and mongo-specific commands.

Solution, that seems appropriate now, is usage of Repositories, for DDD's aggregation roots.
The idea is to stop "string plague" right at repository level. The rule of thumb - do not allow any Business Logic at repository, and do not allow any MongoCollection usages, on any layer, above than repository.

2. Plan yours select carefully

While working with SQL database, most of the time, complex and fast queries can be built, against any reasonable database structure.
So, typical workflow were to build lean domain model, persist it to database, in a way, your's ORM supports, and only than you can start thinking about querying data.
Only in rare cases data structure can be so in-efficient, that it will require refactoring.

Using mongo, you should always think upfront about querying data, and pre-compute a lot of things, before insertion of the document.
To make queries more efficient, we have redesigned storage structure of our data, already 3 times, in just 2 months!

3. None of yours assumptions SQL assumptions can be applied to mongo

If you'll try to bring any assumptions, about tables from SQL world to mongo, it will bite you back soon! Even most basic ones should be checked with mongo documentation.
A part of our application were build, with assumption, that no duplicated records can be returned from collection. After few "impossible" exceptions, I have realized, that sometimes records can be duplicated, if you are using cursor feature. It's not bad by itself, but thanks to my implication, that this is impossible, a lot of code should be re-tested and re-factored, to handle such cases.

4. Schema-less does't mean, that you should't care about it.

My first impression, were "Woo-hoo! No more boring alter-table scripts, just add a field, that's it". But actually, whole responsibility of management database versions is moved to your's build script or DAL code.

Tuesday, March 1, 2011

.Net IoC performance comparison

Finally, I have compared performance of most widely-used IoC containers.
I'am clearly understand, that for IoC performance, in most cases, is not an issue, but I were still curious enough to test.
Here are the results:
Name Total PerRequest
Structure Map 377ms 0.377ms
Autofac 287ms 0.287ms
Unity 351ms 0.351ms
Ninject 2638ms 2.638ms
Manual 1ms 0.001ms

Test source is available via GitHub
Assumptions, behind the test, is optimized for Web scenario, where several threads request classes in different scopes.