Playing with mongo.db

For the ones who doesn’t knew, mongodb is a scalable, agile and document-oriented database.

One of it’s best features that I like and use is map/reduce. This feature is very useful for batch processing of data and aggregation operations.

Example:

If we have a collection like the following one:

{ “_id” : ObjectId(“1111”), “make” : [ “Maker1”], “models” : [ “Model1” , “Model2” ]}
{ “_id” : ObjectId(“1111”), “make” : [ “Maker2”], “models” : [ “Model3” ]}
{ “_id” : ObjectId(“1111”), “make” : [ “Maker1”], “models” : [ “Model2]}

we can use map reduce to number all the combinations makers – models from this collection :

Creating a map function
first of all we have to prepare the initial collection. Because for this test, we want only to count all the combinations Maker-Model we can create a “map” function like the following:

map = function() {
	if (typeof this.make == "undefined") {
		emit("null", { count : 1 });
	} else {
		for ( var i in this.make) {
			if (typeof this.models == "undefined") {
				emit(String(this.make[i]).toLowerCase(), {count : 1});
			} else {
				for ( var j in this.models) {
					emit(String(this.make[i]).toLowerCase() + "-" + String(this.models[j]).toLowerCase(), {
						count : 1
					});
				}
			}
		}
	}
};

second we have to create a reduce function. Like its name, this function we reduce the entire collection created in “map” function to whatever we want. In this case we will sum all the values.

reduce = function(key, values) {
	var total = 0;
	for ( var i = 0; i < values.length; i++) {
		total += values[i].count;
	}
	return {
		count : total
	};
};

calling the mapReduce function

var results = db.SearchForm.mapReduce(map,reduce);

In the end, we have to write “result” on console, to see the output of the operation.
The output may look like this, if you have enough data in the collection :

> result
{
	"result" : "tmp.mr.mapreduce_1306180705_32",
	"timeMillis" : 215937,
	"counts" : {
		"input" : 3336034,
		"emit" : 3166304,
		"output" : 1452
	},
	"ok" : 1,
}

Leave a Reply

Your email address will not be published. Required fields are marked *