如何检测MongoDB map/reduce中的re-reduce阶段?

How to detect the re-reduce stage in MongoDB map/reduce?

我使用以下 map/reduce 设置将一些数据收集到数组中:

map: function() { emit(this.key, [this.item]); },
reduce: function(key, values) {
                     var items = [];
                     values.forEach( function(value) {items.concat(value.item);} );
                     return items;
         },
out: {reduce: "result_collection"}

我想改进代码并检测生成的集合在重新归约阶段是否已更改(当 mongo 使用 "result_collection" 的当前内容调用归约时)。

换句话说,如何知道 Map 发出的任何文档包含 "item" 而 "result_collection" 中还不存在(当然,在相同的键下)?

此信息可以在某些进一步的处理阶段提供帮助,例如查询 "result_collection" 以获取在 map/reduce 阶段更新的文档。

如果一定要这样做,在所有reduction完成后使用finalize函数调整value。您必须向 reduce 函数添加更多逻辑来处理修改后的输出。

我将向您展示一个示例,其中包含由以下 mapreduce 函数定义的简单 map-reduce:

var map = function() { emit(this.k, this.v) }
var reduce = function(key, values) { return Array.sum(values) }

在看起来像 { "k" : 0, "v" : 1 } 的文档上,由上述函数定义的 map-reduce 生成看起来像 { "_id" : 0, "value" : 17 } 的结果文档。定义一个finalize函数来修改最终文档:

var finalize = function (key, reducedValue) { return { "m" : true, "v" : reducedValue } }

现在修改 reduce 来处理 values 的一个元素,它可能是上述形式的对象:

var reduce2 = function(key, values) { 
    var sum = 0; 
    for (var i = 0; i < values.length; i++) { 
        if (typeof values[i] == "object") { sum += values[i].v }
        else { sum += values[i] } 
    }

    return sum 
}

输出看起来像

{ "_id" : 0, "value" : { "m" : true, "v" : 14 } }
{ "_id" : 1, "value" : { "m" : true, "v" : 34 } }
{ "_id" : 2, "value" : { "m" : true, "v" : 8 } }

这样您就可以知道 value.m 修改了什么。您的进一步处理可以将 v.m 设置为 false 这样您将在每次 map-reduce 后看到尚未处理的内容。