MongoDB Map减少在高数据量下返回意外结果



我是新的PHP以及mongo数据库和我有一个80000条记录的数据集,这是一个本地部署。

My Data Structure is simple:

(
    [_id] => MongoId Object
        (
            [$id] => 53c146aebc7d867d058b94b3
        )
    [name] => Mark
    [txnType] => Borrowed
    [amount] => 5876
)

我正在运行如下定义的Map Reduce作业:

$map = new MongoCode("function ()
{
    { 
        emit({name:this.name,type:this.txnType},this.amount);
    }
}");
$reduce = new MongoCode("
    function (key, values)
    {
        var total=0;
        var count=0;
        for (var i in values) { 
            if (!isNaN(values[i])) {
                total+=values[i];
            };
            count++;
        }
        return {total:total, count:count};
    }
    ");
$sales =  $db->command(array(
    "mapreduce" => "data", 
    "map" => $map,
    "reduce" => $reduce,
    "out" => "sales"
    ));

这个概念基本上是有4个人可能有类型为借入,出售,购买和借出的交易。每条记录代表一个txn。

我想创建一个数据枢轴获取数据为:

名称:类型:Total Amount: Count of Txns

支撑数据的方式是混乱的。这些计数加起来应该是80000,但实际上加起来只有216。

我不明白为什么会发生这种事。有人能帮帮我吗?我做错了什么,要纠正什么。

我需要的是为这笔交易草拟一份分析报告。

问题是您的emit输出的格式与您的reduce相同。

下面是你输出的值:

this.amount

下面是你从reduce返回的结果:

return {total:total, count:count};

为了使reduce在重新执行reduce操作时能够正常工作(请记住,对于同一个键值,reduce可能被调用零、一次或多次),您必须发出这样的格式:

emit({name:this.name,type:this.txnType},{ total: this.amount, count: 1} );

因此你的reduce函数现在应该是:

    var total=0;
    var count=0;
    for (var i in values) { 
        if (!isNaN(values.total[i])) {
            total+=values.total[i];
        };
        count+=values.count;
    }
    return {total:total, count:count};

MongoDB中mapReduce的两个最重要的规则:

  1. 以与reduce函数返回的完全相同的格式发出值

  2. 结构减少,以便每个键可以调用零,一次或多次

请注意,使用聚合框架可以更高效、更快地执行相同的聚合,如下所示:

db.collection.aggregate( {$group: 
    { _id : {name: "$name", type: "$txnType"},
      total: {$sum: "$amount"},
      count: {$sum: 1}
    }
}

相关内容

  • 没有找到相关文章

最新更新