在mongodb中重新加入分裂的MapReduce阵列
Rejoining Split MapReduce Arrays in Mongo
我正在学习mapReduce。在一个用户集合上调用下面的map reduce函数:
function () {
m = function () {
emit(this.city, {num:1, arr:this});
}
r = function (key, arr_values) {
var resultArray = [];
var count = 0;
arr_values.forEach(function (value) {
resultArray.push(value);
count++;
});
return {num:count, arr:resultArray};
}
res = db.AdsOnPage.mapReduce(m, r, {out:"ReducedCollection"});
}
最终得到了我所需要的——"city"作为键,然后是该城市的用户数组作为值。但实际上它给我的是一堆嵌套数组。我想这是分片的结果吧?但我如何重新加入一切?现在,结果看起来像这样:
{
"city":"Chicago",
"value" : {
"num" : 2.0,
"arr" : [{
"num" : 2.0,
"arr" : [{
"num" : 1.0,
"arr" : [{
<user doc is here>
}]
}, {
"num" : 1.0,
"arr" : [{
<user doc is here>
}]
}]
}
.......
for many many arrays
为什么会发生这种情况?有没有办法重新加入我的结果到一个连贯的单一数组?
与分片无关,这与Map/Reduce逻辑有关。
从map
函数得到的value
需要具有与从reduce
返回的相同的形状。
请记住,reduce
可以多次运行。事实上,在分片的情况下,它将为每个分片运行一次,然后再由mongos
发出请求。
你在想当你跑的时候会发生什么
reduce(key, [a,b,c])
要使Map/Reduce工作,输出必须与以下相同:
reduce(key, [a, reduce(key, [b,c]) )
OR
reduce(key, [reduce(key, [a,b]), c] )
在您的例子中,reduce(key, [b,c])
返回一个数组,因此您得到以下内容:
reduce(key, [a, reduce(key, [b,c]) )
=> reduce(key, [a, [b,c] ])
注意到额外的数组了吗?这就是为什么你得到嵌套。
解决这个问题需要两部分。
- 如果
values
是一个数组,那么emit
应该输出一个包含一个项目的数组。 - 当你做这个改变时,
arr_values
将是一个"数组的数组"。你必须正确地组合它们。
希望这能给你指明正确的方向。有关更详细的调试方法,您可能需要查看故障排除M/r页面
我使用数组函数array. isarray (param)和indexOf(param)来解决这种问题,但我在堆栈数组中推送唯一元素。
if(Array.isArray(param)) {
for(var i in param) {
if(stack.indexOf(param[i]) == -1)
arr.push(param[i]) ;
}
}
else {
if(stack.indexOf(param) == -1)
arr.push(param) ;
}
你可以尝试Array.isArray()
- 使用正则表达式捕获“”并分割成阵列
- AngularJS卡片转盘:将卡片返回到阵列的末尾
- 从不同的对象创建阵列
- 阵列中随机图像的问题
- 在特定条件下从存储在localStorage中的阵列中删除对象
- 如何将所有同级存储在动态本地存储阵列中
- 从localStorage添加和检索阵列
- angular.注射器阵列值未返回当前值
- 流星蒙戈的返回阵列
- 从2D RGB阵列创建图像
- 构建画布RGB值的2D阵列
- 图像阵列预加载时显示沙漏光标
- 当会话存储阵列中存在大量元素时,如何从中删除元素
- 相对于角度控制器中的另一个阵列过滤阵列项目
- 为什么不是't我的“;虚拟的“;阵列工作
- Json阵列的详细信息显示在三页的angularjs中
- 来自阵列的大小为N的组合
- Mongodb mapreduce optimization
- 用替换或拼接替换阵列中的编号
- 在mongodb中重新加入分裂的MapReduce阵列