【问题标题】:MongoDB Map/Reduce strugglesMongoDB Map/Reduce 之争
【发布时间】:2011-03-23 18:36:45
【问题描述】:

给定这样的文件:

{    "_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  }

以及以下 Map/Reduce 函数:

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}; 
}; 

我得到以下输出:

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

为什么 DocName 为空?

【问题讨论】:

标签: mapreduce mongodb


【解决方案1】:

问题非常像 Srdjan 指出的那样 - 在您的 forEach 函数中,您实际上并没有对父文档的引用。

如果您将地图功能更改为此,它可以工作:

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

所以,在循环之前将文档名称分配给一个变量,然后在其中使用它

【讨论】:

【解决方案2】:

如果我认为这是正确的,并且我想我是,那么在发出函数中的 this 并不是您所期望的。

因为它在函数内部,所以 this 指的是每一行,而不是父文档。试试这个:

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

【讨论】:

  • 您的意思是“var parent = this;”吗?那也行不通。它把我的 TrendValue 也搞砸了 0!
  • 这就是我的意思,是的。看看 Kyle Banker 的博客,他在 mongo 中的 map/reduce 上有一篇非常好的博文。我敢打赌你错过了一件小事。
  • 关于 Map/Reduce 的问题在于,无论我阅读了多少博客和文章,总有一些愚蠢的语法案例在任何地方都没有涉及。不过我确实读过 Banker 的博客。
  • 是的,即使是官方文档也不涵盖您的情况。您可能会在#mongodb IRC 频道中获得更多帮助。
猜你喜欢
  • 1970-01-01
  • 2013-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多