让我解释一下我的问题。所以我在MongoDB中运行简单的mapReduce查询,我得到了非常奇怪的结果,对我来说没有任何意义。也许有人会解释它或找到一些错误。所以…
我正在运行2.6.2版本的mongoDB集合中的每个文档都有结构(我有~2000个文档)
{
_id:...,
data:{
type:'myType'
}
}
map function
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();为什么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}
]
]
}
]
}
}
您错过了文档中的重要概念,它引用了:
"MongoDB可以对同一个键多次调用reduce函数。在这种情况下,该键的reduce函数先前的输出将成为该键的下一次reduce函数调用的输入值之一。"
,后来:
这意味着你必须从你的"reduce"操作返回本质上相同的数据签名,因为你从你的"map"函数。这是因为mapReduce不会一次为一个键"减少"所有文档。它是分步骤完成的。"…返回对象的类型必须与map函数发出的值的类型相同。"
所以被"部分还原"的东西可以再次被reduce函数调用。它实际上一次处理大约30个左右的项目,并且由于您的"reduce"不会发出与"map"相同的输出,因此在下一次访问reducer时,数据的处理方式不同。
这就是为什么你的结果会出现。为了解决这个问题,reduce需要输出与"input"中预期的相同的"类型"的数据:
var reduce = function(key, values) {
var res = { "count": 0 }
values.forEach(function(value) {
res.count += value.count;
});
return res;
}
因为输出和输入的数据是一样的,所以你要正确地"计数"你的键出现