user2279319
user2279319

Reputation: 1

Mongodb map reduce trivial query

I have a below map:

var mapFunction = function() {

if(this.url.match(/http:\/\/test.com\/category\/.*?\/checkout/)) {
var key=this.em;
var value = {
    url : 'checkout',
    count : 1,
    account_id:this.accId

}emit(key,value); };
if(this.url.match(/http:\/\/test.com\/landing/)) {
var key=this.em;
var value = {
    url : 'landing',
    count : 1,
    account_id:this.accId

}emit(key,value); };

}

Then I have defined reduce something like below:

var reduceFunction = function (keys, values) {
var reducedValue = {count_checkout:0, count_landing:0};
for (var idx = 0; idx < values.length; idx++) {
    if(values[idx].url=='checkout'){
        reducedValue.count_checkout++;
    }
    else {
        reducedValue.count_landing++;
    }
}
return reducedValue;
} 

Now, lets say I have only 1 record:

{
        "_id" : ObjectId("516a7cff6dad5949ddf3f7b6"),
        "ip" : "1.2.3.4",
        "accId" : 123,
        "em" : "[email protected]",
        "pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
        "url" : "http://test.com/category/prr/checkout",
        "domain" : "www.test.com",
        "pgUdTs" : ISODate("2013-04-14T09:55:11.682Z"),
        "title" : "Test",
        "ua" : "Mozilla",
        "res" : "1024*768",
        "rfr" : "www.google.com"
}

Now if I fire my map reduce like below:

db.test_views.mapReduce(mapFunction,reduceFunction,{out:{inline:1}})

The I get below result returned:

{
          "_id" : "[email protected]",
          "value" : {
                  "url" : "checkout",
                  "count" : 1,
                  "account_id" : 123
          }
  }

So, its basically returning me the map. Now, if I go a add another document for this email id. Finally it becomes something like below.

{
        "_id" : ObjectId("516a7cff6dad5949ddf3f7b6"),
        "ip" : "1.2.3.4",
        "accId" : 123,
        "em" : "[email protected]",
        "pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
        "url" : "http://test.com/category/prr/checkout",
        "domain" : "www.test.com",
        "pgUdTs" : ISODate("2013-04-14T09:55:11.682Z"),
        "title" : "Test",
        "ua" : "Mozilla",
        "res" : "1024*768",
        "rfr" : "www.google.com"
}
{
        "_id" : ObjectId("516a7e1b6dad5949ddf3f7b7"),
        "ip" : "1.2.3.4",
        "accId" : 123,
        "em" : "[email protected]",
        "pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
        "url" : "http://test.com/category/prr/checkout",
        "domain" : "www.test.com",
        "pgUdTs" : ISODate("2013-04-14T09:59:55.326Z"),
        "title" : "Test",
        "ua" : "Mozilla",
        "res" : "1024*768",
        "rfr" : "www.google.com"
}

Then, I go again and fire the map reduce, it gives me proper results

{
         "_id" : "[email protected]",
         "value" : {
                 "count_checkout" : 2,
                 "count_landing" : 0
         }
 }

Can anyone please help me out in understanding why it returns me a map for single document and doesn't do the counting in reduce.

Thanks for help.

-Lalit

Upvotes: 0

Views: 628

Answers (2)

Tomer Weller
Tomer Weller

Reputation: 2812

The reduce function should return the same type of value objects as the map function emits.
Like you've experienced, when there's a single value associated with a key - the reduce function will not be called at all .

From the MongoDB MapReduce Documentation:

Requirements for the reduce Function:
...
the type of the return object must be identical to the type of the value emitted by the map function to ensure that the following operations is true:
reduce(key, [ C, reduce(key, [ A, B ]) ] ) == reduce( key, [ C, A, B ] )

Upvotes: 0

Stennie
Stennie

Reputation: 65303

Can anyone please help me out in understanding why it returns me a map for single document and doesn't do the counting in reduce.

The Reduce step combines documents with the same key into a single result document. If you only have one key in the data emitted by your Map function, the data is already "reduced" and the reduce() will not be called.

This is the expected behaviour of the MapReduce algorithm.

Upvotes: 1

Related Questions