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

时间:2015-02-09 09:22:03

标签: mongodb mapreduce

我使用以下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发出的任何文件都包含“result_collection”中不存在的“item”(当然在同一个键下)?

此信息有助于进一步处理阶段,例如查询“result_collection”以获取在map / reduce阶段期间已更新的文档。

1 个答案:

答案 0 :(得分:0)

如果必须这样做,请在完成所有缩减后使用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之后看到尚未处理的内容。