2

For my Rails+MongoId application i need to aggregate data for statistical purposes. My model is rapresenting a general Web application that has_many versions (aka: bundles) and relative users activations:

App = {
  "_id" : ObjectId("4ff2e2eab528571384000eb4"),
  "name" : "my app",
  "category_id": "4ff2e2eab528571384000cc0",
  "bundles": [{
    "_id" : ObjectId("4ff2e2eab528571384000dca"),
    "activations" : [{
      "user" : "user_0",
      "_id" : ObjectId("4ff2e2eab528571384000dd0")
     },
     ... 
  },
  ...
  ]
}

Now, what i have to do is to return the number of ACTIVATIONS per application CATEGORY_ID, alĂ :

results = [
  {
    "_id": "4ff2e2eab528571384000cc0",
    "value": 243
  },
  ...
]

I can easily obtain the total number of BUNDLES per CATEGORY_ID with this mapreduce function:

map = function() { 
  for (var bundle in this.bundles) { 
    emit(this.category_id, 1); 
  }
};
reduce = function(key, values) { 
  var sum = 0; 
  values.forEach(function(value) { 
    sum += value; 
  }); 
  return sum; 
};

But, when i try to enter one level deeper, i do obtain no results at all:

map = function() { 
  for (var bundle in this.bundles) { 
    for (var activation in bundle.activations) {
      emit(this.category_id, 1); 
    }
  }
};
reduce = function(key, values) {
  var sum = 0; 
  values.forEach(function(value) { 
    sum += value;
  });
  return sum;
};

Any idea is greatly appreciated. Best regards

Mike Costa

Mike Costa
  • 41
  • 4

2 Answers2

1

Thanks for the tips NOMOA,

i'm able solve my problem by modifying the map function as the following:

map = function() { 
  var len = this.bundles.length; 
  for (var i = 0; i < len; i++) {
    if (this.bundles[i].activations !== undefined) { 
      emit(this.category_id, this.bundles[i].activations.length);
    } 
  }
};

I had to remove the for..in contruct in favor of a more traditional for..i++, add an "undefined" check (as you suggest) and it works perfectly (i also avoid the double loop)!

Best regards M. Costa

Mike Costa
  • 41
  • 4
0

Are you sure that your map reduce function run correctly?

I guess you should check if bundle.activations is non null. Check within server logs for any errors. Also with server logs you can view debug print statements.

nomoa
  • 1,043
  • 6
  • 18