Question

I have document like this:

{
   "_id": ObjectId("4d17c7963ffcf60c1100002f"),
   "title": "Text",
   "params": {
     "brand": "BMW",
     "model": "i3"
    }
}

{
   "_id": ObjectId("4d17c7963ffcf60c1100002f"),
   "title": "Text",
   "params": {
     "brand": "BMW",
     "model": "i5"
    }
}

What i need is the count of every params values. like:

brand
---------
BMW (2)

model
---------
i3 (1)
i5 (1)

I think i have to write map/reduce functions. How can i do this? Thanks.

Was it helpful?

Solution

I think i have to write map/reduce functions.

Yes you need a map-reduce for this. For some simple map-reduce examples, please look here.

For your particular case, you first need to change your expectation of the output. The output of the map / reduce is a collection. The collection will look (in your case) something like this:

{ key : { 'brand' : 'bmw' }, value : 2 }
{ key : { 'model' : 'i5' }, value : 1 }

To generate this set you will need a "map" function and a "reduce" function. The "map" function will emit a key and a value. The key is each element of params, the value is the count of 1. The "reduce" function accepts a key and an array of values and returns just a single value. Your question is basically the same as this example on the MongoDB site:

map = function() {
    if (!this.params) {
        return;
    }
    for (index in this.params) {
        emit(this.params[index], 1);
    }
}

reduce = function(previous, current) {
    var count = 0;

    for (index in current) {
        count += current[index];
    }

    return count;
}

OTHER TIPS

In your map function enumerate the properties of the params property of the this object. For each property you find call emit with a key that contains both the name of the property and the value of the property. Pass 1 as the value. e.g. emit({'brand','BMW'}, 1) but obviously using variables not constants!

In your reduce function you are passed a key and an array of values. Sum these values and return the sum. Even though the initial array will be all 1's don't be tempted to use the length of the array because the reduce function can be called iteratively.

You can group the results afterwards from the result collection, applying an index if necessary for performance.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top