mongodb - Map/Reduce to get group() Result -


i'm trying aggregate bunch of user profile data in our app. each user has embedded profile document gender, , ethnicity attribute.

{   'email': 'foo@email.com',   'profile': {     'gender': 'male',     'ethnicity': 'hispanic'   } } 

if use group function so:

db.respondents.group({   key: {},   initial: {'gender': {'male':0,'female':0}, 'ethnicity': {}, 'count': 0},   reduce: function (user, totals) {     var profile = user.profile;      totals.gender[profile.gender]++;     totals.ethnicity[profile.ethnicity] = (totals.ethnicity[profile.ethnicity] || 0);     totals.ethnicity[profile.ethnicity]++     totals.count++;  } }); 

i result in form want:

{     "gender" : {         "male" : ###,         "female" : ###     },     "ethnicity" : {         "caucasian/white" : ###,         "hispanic" : ###,                     ...      },     "count" : ### } 

i'm having trouble getting work map/reduce command, using different reduce function of course. i'm not sure how totals add up. incorrect. i'm aware output reduce has in same format input map, feel i'm missing in way reduce works...

in response @jenna, input looks like:

{   'email': 'foo@email.com',   'profile': {     'gender': 'male',     'ethnicity': 'hispanic'   } } 

and functions are:

function map(){   emit('demographics', this.profile) }  function reduce (key, values) {   var reduced = {'gender': {'male':0,'female':0}, 'ethnicity': {}, 'count': 0};   values.foreach(function(value) {     reduced.gender[value.gender]++;     reduced['ethnicity'][value.ethnicity] = (reduced['ethnicity'][value.ethnicity] || 0);     reduced['ethnicity'][value.ethnicity]++;     reduced.count++;   });   return reduced; } 

and output is:

{     "_id": "demographics",     "value": {       "gender": {         "male": 76.0,         "female": 64.0       },       "ethnicity": {         "caucasian/white": 109.0,         "other": 5.0,         "asian": 10.0,         "african-american": 8.0,         "hispanic": 7.0,         "native american": 1.0       },       "count": 141.0     } } 

the output way incorrect since there on 100k records in database.

the reduce function may called again on output earlier call. correct output map should same output reduce. current map function returns different reduce function. try this:

function map(){   result = {'gender': {'male': 0, 'female': 0}, 'ethnicity': {}, 'count': 1};   result['gender'][this.gender] = 1;   result['ethnicity'][this.ethnicity] = 1;   emit('demographics', result); }  function reduce (key, values) {   var reduced = {'gender': {'male':0,'female':0}, 'ethnicity': {}, 'count': 0};   values.foreach(function(value) {     reduced['gender']['male'] += value['gender']['male'];     reduced['gender']['female'] += value['gender']['female'];     for(ethnicity in value['ethnicity']){       if(reduced['ethnicity'][ethnicity] === undefined)         reduced['ethnicity'][ethnicity] = 0       reduced['ethnicity'][ethnicity] += value['ethnicity'][ethnicity]     }     reduced['count'] += values.count;   });   return reduced; } 

Comments

Popular posts from this blog

c# - SVN Error : "svnadmin: E205000: Too many arguments" -

c++ - Using OpenSSL in a multi-threaded application -

All overlapping substrings matching a java regex -