MongoDB mapReduce多键值计数问题

时间:2014-08-02 01:34:48

标签: javascript mongodb mapreduce

让我解释一下我的问题。所以我在MongoDB中运行简单的mapReduce查询,我得到了非常奇怪的结果,对我来说没有任何意义。愿有人解释或发现一些错误。所以...

我正在运行mongoDB的2.6.2版本 集合中的每个文档都有结构(我有~2000个文档)

{
  _id:...,
  data:{
    type:'myType'
  }
}

地图功能

var map = function() {
  if(this.data.type== 'myType123') {
    emit(this.data.type, {count:1});
  }
}

减少功能

var reduce = function(keyCustId, allElems) {
  var res = {};
  res.example = allElems;
  return res;
}

我尝试运行

var results = db.myCollection.mapReduce( map, reduce,{ out: "map_reduce_example" });

现在检查结果db [results.result] .find()。pretty();并且它给我带来了类似的东西.WHY MONGO让结果如此痴迷?我的地图或缩小功能是错误的吗?如果在map-> emit(key,value)中我传递值不是作为对象而只是一个整数,那么一切正常。请帮我弄清楚这个mongoDB的噩梦......谢谢。

{
_id:'myType123',
value:{
  example:[
   {count:1},
   {count:1},
   {count:1},
   {count:1},
   {example: [
     {count:1},
     {count:1}, 
     {example:[
        {count:1},
        {count:1},
        {count:1}
     ]
   ]
   }
  ]
}
}

1 个答案:

答案 0 :(得分:1)

你错过了the documentation中引用的重要概念:

  

" MongoDB可以为同一个密钥多次调用reduce函数。在这种情况下,该键的reduce函数的先前输出将成为该键的下一个reduce函数调用的输入值之一。"

后来:

  

" ...返回对象的类型必须与map函数发出的值的类型相同。"

这意味着您必须从" reduce"中返回基本相同的数据签名。通过你的"地图"进行操作功能。这是因为mapReduce不会减少"一次锁定所有单个文档的文档。它是分步进行的。

所以已经部分减少了#34;可以再次通过reduce函数调用。事实上,它实际上会一次处理大约30个左右的项目,因为你的"减少"不会发出与" map"相同的输出,在下一次减速器行程中,数据的处理方式也不同。

这就是你出现的结果的原因。为了解决这个问题,reduce需要输出相同的"类型" "输入":

中预期的数据
var reduce = function(key, values) {
  var res = { "count": 0 }
  values.forEach(function(value) {
      res.count += value.count;
  });
  return res;
}

由于这是与进入时相同的数据,因此您的正确"计数"你的关键事件。