reduce函数可以调用一次,使用一个键和all corresponding values(但仅当该键有多个值时——如果该键只有一个值,则根本不会调用它).
它也可能被调用多次,每次使用一个键,而只有一个subset of the corresponding values,以及之前针对该键的reduce结果.这个场景被称为re-reduce.为了支持re reduce,你的reduce函数应该是idempotent.
幂等约简函数有两个关键特性:
- reduce函数的return value应该在它接受的same format as the values中.因此,如果reduce函数接受字符串数组,那么该函数应该返回一个字符串.如果它接受具有多个属性的对象,它应该返回一个包含这些相同属性的对象.这样可以确保在调用函数时,函数不会因前一次reduce的结果而中断.
- Don't make assumptions based on the number of values.它能接受.不能保证
values
参数包含给定键的all个值.所以在计算中使用values.length
是非常危险的,应该避免.
Update:在最近的MongoDB版本中,以下两个步骤不是必需的(甚至是可能的,我还没有判断).如果在map reduce options中指定输出集合,它现在可以为您处理以下步骤:
{ out: { reduce: "tempResult" } }
如果reduce函数是幂等函数,那么在映射多个集合时应该不会有任何问题.只需重新减少每个集合的结果:
第一步
在每个必需的集合上运行map reduce,并将结果保存在单个临时集合中.您可以使用finalize function:
finalize = function (key, value) {
db.tempResult.save({ _id: key, value: value });
}
db.someCollection.mapReduce(map, reduce, { finalize: finalize })
db.anotherCollection.mapReduce(map, reduce, { finalize: finalize })
第二步
在临时集合using the same reduce function上运行另一个map reduce.map函数是一个简单的函数,用于从临时集合中 Select 键和值:
map = function () {
emit(this._id, this.value);
}
db.tempResult.mapReduce(map, reduce)
这第二个map reduce基本上是一个re reduce,应该会提供您需要的结果.