我在 MongoDB 中使用 MapReduce,我想我已经完全理解了所有这些,除了一个我仍然不明白的部分:reduce
运行了多少次?
例如,我有一个“项目”集合,每个项目都有一个“类别”。这是测试数据(用 javascript 编写,用于 node.js 单元测试):
var i = 0;
var dummyCategories = [
{ categoryId:(++i), categoryName:'Category '+i }, // [0] 1
{ categoryId:(++i), categoryName:'Category '+i }, // [1] 2
{ categoryId:(++i), categoryName:'Category '+i }, // [2] 3
{ categoryId:(++i), categoryName:'Category '+i }, // [3] 4
{ categoryId:(++i), categoryName:'Category '+i } // [4] 5
];
i=0;
var dummyItems = [
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [0] 1
category: dummyCategories[0]
},
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [1] 2
category: dummyCategories[1]
},
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [2] 3
category: dummyCategories[2]
},
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [3] 4
category: dummyCategories[3]
},
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [4] 5
category: dummyCategories[4]
},
{ itemId: 'TestItem' + (++i), title: 'Test Item ' + i, // [5] 6
category: dummyCategories[0]
}
];
有 6 个项目,5 个类别,其中一个类别出现两次,其余类别出现一次。
在我的map
功能中,我正在发射(this.category.categoryId, { items: 1 });
. (完整版除了 # of items 之外,还包括 value 对象中的其他指标,但无论哪种方式,这种行为都是相同的。)
我的reduce
功能如下所示:
function reduce(key, values) {
var totals = {
items: 0
};
for (var i = 0; i < values.length; i++) {
totals.items += values[i].items;
}
return totals;
};
(map 中的输出结构与 reduce 中的输出结构相同,因为它需要如此。)
所以我通过 mapReduce 运行verbose=true
它,它显示了这些统计信息:
计数:{输出:5,发射:6,减少:1,输入:6}
input:6 有意义,有 6 个文档。emit:6 是有道理的,它为每个文档发出 1 个类别。output:5 有意义,有 5 个类别。但是为什么 reduce 只运行一次呢?
现在写出来,它似乎为每个出现多次的发出键运行reduce。因此,当一个键只发出一次时,它不会减少它。那是对的吗?确定减少运行次数的数学公式是什么?
谢谢!