【问题标题】:How to detect the re-reduce stage in MongoDB map/reduce?如何检测 MongoDB map/reduce 中的 re-reduce 阶段?
【发布时间】:2015-04-08 23:43:34
【问题描述】:

我使用以下 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 阶段已更新的文档。

【问题讨论】:

    标签: mongodb mapreduce


    【解决方案1】:

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

    我将向您展示一个由以下 map 和 reduce 函数定义的简单 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 之后看到尚未处理的内容。

    【讨论】:

    • 这个方案违反了 map/reduce 的要求,不是吗? map、reduce 和 finalize 的返回值必须是相同的类型。
    • 哪些 map/reduce 要求? MongoDB 没有强制执行任何此类要求。这个想法是有效的,示例代码有效。我确实同意这不是一件很棒的事情,但我也相信用例是值得的,所以我在回答前加上“如果你必须这样做”:D。
    • 要求是in the doc和more explanation。我同意您的代码可以工作,但它可以在更复杂的用例中工作吗?
    • 浏览这些要求,我认为我的示例满足了所有要求。 finalize 函数不必返回与其他任何东西相同的类型。有没有你可以指出违反的?我也将我向您展示的内容称为策略,以我的代码为例。该策略的想法是合理的。您必须为您的案例编写代码来实现它,这可能比示例更复杂,并且与简单地处理整个输出集合、更改和未更改的文档等类似的处理相比,可能不值得维护。
    • 确实,我错误地为 finalize 函数分配了额外的要求。显然,它的返回类型可能与 map 和 reduce 输出不同。这让我感到困惑“......将reduce函数应用于新文档和现有文档,并用结果覆盖现有文档”
    猜你喜欢
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多