A C# Developer's First Thoughts on MongoDB

After working with RavenDB over the year, I just started looking into MongoDB. I worked with MongoDB a year ago or so in a small project but my knowledge was mostly rusty and I don't want that to happen again :) So, here I'm, documenting what my second thoughts are :)
12 April 2014
4 minutes read

Related Posts

After working with RavenDB over the year, I just started looking into MongoDB. I worked with MongoDB a year ago or so in a small project but my knowledge was mostly rusty and I don't want that to happen again :) So, here I'm, documenting what my second thoughts are :) The TL;DR is that: I'm loving it but the lack of transaction sometimes drifts on a vast dark sea. It's OK through. The advantages generally overcomes this disadvantage.

Loved the Mongo Shell

First thing I liked about MongoDB is its shell (Mongo Shell). 

3d6f5fdd4be53096b6992d5b84b0d7be

It makes it insanely easy for you to get used to MongoDB. After running the mongod.exe, I fired up a command prompt and navigated to mongo.exe directory and entered the mongo shell. Mongo Shell runs pure JavaScript code. That's right! Anything you know about JavaScript is completely valid inside the mongo shell. Let's see a few things that you can do with mongo shell.

You can list the databases on your server: show dbs

2

You can see which database you are connected to: db

3

You can switch to a different database: use <database name here>

4

You can see the collections inside the database you are on: show collections

5

You can save a document inside a collection: db.users.save({ _id: "tugberk", userName: "Tugberk" })

6

You can list the documents inside a collection: db.users.find().pretty()

7

You can run a for loop:

for(var i = 0; i < 10; i++) { 
	db.users.save({ 
		_id: "tugberk" + i.toString(), 
		userName: "Tugberk" + i.toString() 
	}) 
}

8

You can run the code inside a js file

9

saveCount.js contains the following code and it just gets the count of documents inside the users collection and logs it inside another collection:

(function() {
     var myDb = db.getSiblingDB('myDatabase'),
         usersCount = myDb.users.find().count();
         
     myDb.countLogs.save({
          count: usersCount,
          createdOn: new Date()
     });
}());

All of those and more can be done using the mongo shell. It's a full blown MongoDB client and probably the best one. I don't know if it's just me but big missing feature of RavenDB is this type of shell.

Loved the Updates

Update operations in MongoDB is just fabulous. You can construct many kinds of updates, the engine allows you to do this fairly easily. The one I found most useful is the increment updates. Increment updates allows you to increment a field and this operation will be performed concurrency in-mind:

db.books.update(
   { item: "Divine Comedy" },
   {
      $inc: { stock: 5 }
   }
)

The above query will update the stock filed by 5 safely.

Not much Love for the .NET Client

MongoDB has an official .NET client but MongoDB guys decided to call this "C# driver". This is so strange because it works with any other .NET languages as well. I have to say that MongoDB .NET client is not so great in my opinion. After coming from the RavenDB .NET client, using the MongoDB .NET client just feels uncomfortable (However, Iā€™m most certainly sure that Iā€™d love its Node.Js client as it would feel very natural).

First of all, it doesn't support asynchronous requests to MongoDB server. All TCP requests are being done synchronously. Also, there is no embedded server support. RavenDB has this and it makes testing a joy. Let's look at the below code which gets an instance of a database:

MongoClient client = new MongoClient("mongodb://localhost");
MongoServer server = client.GetServer();
MongoDatabase db = server.GetDatabase("mongodemo");

There is too much noise going on here. For example, what is GetServer method there? Instead, I would want to see something like below:

MongoClient client = new MongoClient("mongodb://localhost");
using(var session = client.OpenSession("myDatabase"))
{
     // work with the session here...
}

Looks familiar :) I bet it does! Other than the above issues, creating map/reduce jobs just feels weird as well because MongoDB supports JavaScript to perform map/reduce operations.

var map =
    "function() {" +
    "    for (var key in this) {" +
    "        emit(key, { count : 1 });" +
    "    }" +
    "}";

var reduce =
    "function(key, emits) {" +
    "    total = 0;" +
    "    for (var i in emits) {" +
    "        total += emits[i].count;" +
    "    }" +
    "    return { count : total };" +
    "}";

var mr = collection.MapReduce(map, reduce);
foreach (var document in mr.GetResults()) {
    Console.WriteLine(document.ToJson());
}

The above code is directly taken from the MongoDB documentation.

Explore Yourself

MongoDB has a nice documentation and you can explore it yourself. Besides that, Pluralsight has a pretty nice course on MongoDB: Introduction to MongoDB by Nuri Halperin. Also, don't miss the Ben's post on the comparison of Map-Reduce in MongoDB and RavenDB.