我正在尝试在mongo shell中运行mongodb上的map reduce.出于某种原因,在reduce阶段,我得到几个相同的键(而不是单个键),所以我得到错误的结果.我不是这个领域的专家,所以也许我做了一些愚蠢的错误.任何帮助赞赏.
谢谢.
这是我的小例子:
我正在创建10000个文档:
var i = 0;
db.docs.drop();
while (i < 10000) {
db.docs.insert({text:"line " + i,index:i});
i++;
}
Run Code Online (Sandbox Code Playgroud)
然后我正在基于模块10进行map-reduce(所以我除了在每个"桶"中获得1000)
db.docs.mapReduce(
function() {
emit(this.index%10,1);
},
function(key,values) {
return values.length;
},
{
out : {inline : 1}
}
);
Run Code Online (Sandbox Code Playgroud)
但是,结果我得到以下结果:
{
"results" : [
{
"_id" : 0,
"value" : 21
},
{
"_id" : 1,
"value" : 21
},
{
"_id" : 2,
"value" : 21
},
{
"_id" : 3,
"value" : 21
},
{
"_id" : 4,
"value" : 21
},
{
"_id" : 5,
"value" : 21
},
{
"_id" : 6,
"value" : 21
},
{
"_id" : 7,
"value" : 21
},
{
"_id" : 8,
"value" : 21
},
{
"_id" : 9,
"value" : 21
}
],
"timeMillis" : 76,
"counts" : {
"input" : 10000,
"emit" : 10000,
"reduce" : 500,
"output" : 10
},
"ok" : 1,
}
Run Code Online (Sandbox Code Playgroud)
Map/Reduce本质上是一种递归操作.特别是,该功能的文档要求reduce
包括以下声明:
MongoDB可以
reduce
为同一个密钥多次调用该函数.在这种情况下,该reduce
键的函数的先前输出将成为该键的下一个reduce
函数调用的输入值之一.
因此,您必须预期输入仅是先前调用计数的数字.以下代码通过实际添加值来实现:
db.docs.mapReduce(
function() { emit(this.index % 10, 1); },
function(key,values) { return Array.sum(values); },
{ out : {inline : 1} } );
Run Code Online (Sandbox Code Playgroud)
现在,emit(key, 1)
在某种程度上更有意义,因为1
不再是用于填充数组的任何数字,而是考虑其值.
作为旁注,请注意这是多么危险:对于较小的数据集,可能偶然给出了正确的结果,因为引擎决定不需要并行化.
归档时间: |
|
查看次数: |
1356 次 |
最近记录: |