1

Given a document like this:

{    "_id": { 
    "$oid": "4d88ca367d190a0aa4e27806"    },    "Rows": [ 
    { 
      "Columns": { 
        "Date": "Tue, 02 Aug 2011 00:00:00 GMT -04:00", 
        "Col2": 33 
        "Col3": 44 
      } 
    }, 
    { 
      "Columns": { 
        "Date": "Mon, 17 Oct 2011 00:00:00 GMT -04:00", 
        "Col2": 55 
        "Col3": 66 
      } 
    }    ],    "DocName": "For My Eyes Only",    "DocIdentifier": 3322445  }

and the following Map/Reduce functions:

function() { 
  this.Rows.forEach(function(bulkcol) { 
    emit(this.DocName, { TrendValue: bulkcol.Columns.Col2 }); 
    }); 
}; 

function(key, values) { 
  var sum = 0; 
  values.forEach(function(currTrend) { 
    sum += currTrend.TrendValue; 
  }); 
  return {DocName: key, TrendValue: sum}; 
}; 

I get the following output:

{ 
  "_id": null, 
  "value": { 
    "DocName": null, 
    "TrendValue": 88 
  } 
} 

Why is the DocName null?

Andrew Orsich
  • 52,935
  • 16
  • 139
  • 134
ForeverLearning
  • 6,352
  • 3
  • 27
  • 33
  • Linking this question to the same on the MongoDB forums: http://groups.google.com/group/mongodb-user/browse_thread/thread/44219c4994e51476 – AdaTheDev Mar 24 '11 at 13:31

2 Answers2

1

The problem is very much as Srdjan indicated - inside your forEach function, you don't actually have a reference to the parent document.

If you change your map function to this, it works:

m = function() {
   var docName = this.DocName;
   this.Rows.forEach(function(bulkcol) {
     emit(docName, { TrendValue: bulkcol.Columns.Col2 });
     });
 };

So, assign the doc name into a variable before the loop, and then use that within it

AdaTheDev
  • 142,592
  • 28
  • 206
  • 200
  • appreciate if you can help ..http://stackoverflow.com/questions/35426213/how-to-group-mongodb-mapreduce-output – user29578 Feb 16 '16 at 09:33
0

If I'm looking at this right, and I'd like to think that I am, the this in the emit function is not what you're expecting it to be.

Since it's inside a function, that this refers to each Row, not the parent document. Try this:

function() {
  this = parent;
  this.Rows.forEach(function(bulkcol) { 
  emit(parent.DocName, { TrendValue: bulkcol.Columns.Col2 }); 
  }); 
}; 
Srdjan Pejic
  • 8,152
  • 2
  • 28
  • 24
  • did you mean 'var parent = this;'? That doesn't work either. It screws up my TrendValue also to 0! – ForeverLearning Mar 23 '11 at 20:32
  • That's what I meant, yeah. Take a look at Kyle Banker's blog, he has a really good blog post on map/reduce in mongo. I'm willing to bet it's a small thing you're missing. – Srdjan Pejic Mar 23 '11 at 20:36
  • The thing about Map/Reduce is no matter how many blogs and articles I read there is always some stupid syntactical case not covered anywhere. I did read Banker's blog though. – ForeverLearning Mar 23 '11 at 20:39
  • Yeah, even the official docs don't cover your case. You might have more help in #mongodb IRC channel. – Srdjan Pejic Mar 23 '11 at 20:45