【问题标题】:Reduce is called several times with the same key in mongodb map-reduce在 mongodb map-reduce 中使用相同的键多次调用 reduce
【发布时间】:2013-10-08 16:07:29
【问题描述】:

我正在尝试在 mongo shell 中的 mongodb 上运行 map reduce。出于某种原因,在减少阶段,我收到了对同一个键的多次调用(而不是单个键),所以我得到了错误的结果。 我不是这个领域的专家,所以也许我犯了一些愚蠢的错误。任何帮助表示赞赏。

谢谢。

这是我的小例子:

我正在创建 10000 个文档:

var i = 0;
db.docs.drop();
while (i < 10000) {
    db.docs.insert({text:"line " + i,index:i});
    i++;
}

然后我基于模块 10 做 map-reduce(所以我除了在每个“桶”中获得 1000 个)

db.docs.mapReduce(
    function() { 
       emit(this.index%10,1);
    },
    function(key,values) {
       return values.length;
    },
    {
    out : {inline : 1}
    }
);

但是,我得到以下结果:

{
    "results" : [
        {
            "_id" : 0,
            "value" : 21
        },
        {
            "_id" : 1,
            "value" : 21
        },
        {
            "_id" : 2,
            "value" : 21
        },
        {
            "_id" : 3,
            "value" : 21
        },
        {
            "_id" : 4,
            "value" : 21
        },
        {
            "_id" : 5,
            "value" : 21
        },
        {
            "_id" : 6,
            "value" : 21
        },
        {
            "_id" : 7,
            "value" : 21
        },
        {
            "_id" : 8,
            "value" : 21
        },
        {
            "_id" : 9,
            "value" : 21
        }
    ],
    "timeMillis" : 76,
    "counts" : {
        "input" : 10000,
        "emit" : 10000,
        "reduce" : 500,
        "output" : 10
    },
    "ok" : 1,
}

【问题讨论】:

    标签: mongodb mapreduce


    【解决方案1】:

    Map/Reduce 本质上是一种递归操作。特别是,documented requirements for the reduce function 包括以下语句:

    MongoDB 可以为同一个键多次调用reduce 函数。在这种情况下,该键的 reduce 函数的先前输出将成为该键的下一次 reduce 函数调用的输入值之一。

    因此,您必须期望输入仅仅是先前调用计算的数字。以下代码通过实际添加值来做到这一点:

    db.docs.mapReduce(
        function() { emit(this.index % 10, 1); }, 
        function(key,values) { return Array.sum(values); }, 
        { out : {inline : 1} } );
    

    现在,emit(key, 1) 在某种程度上更有意义,因为1 不再只是用于填充数组的任何数字,而是考虑了它的值。

    作为旁注,请注意这是多么危险:对于较小的数据集,可能会意外给出正确的结果,因为引擎认为不需要并行化。

    【讨论】:

    • 是的,map/reduce 有点像 XML:它看起来很简单,但不知何故它令人困惑并且有很多陷阱:/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多