【问题标题】:MongoDB Map Reduce returning unexpected results in high data VolumeMongoDB Map Reduce 在高数据量中返回意外结果
【发布时间】:2014-07-12 17:33:39
【问题描述】:

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

我的数据结构很简单:

(
    [_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 个人可能有类型为 Borrowed、Sold、Purchase 和 Lent 的交易。每条记录代表一个 txn。

我只想创建一个数据透视,将数据获取为:

名称:类型:总金额:Txns 计数

支撑的数据有些混乱。加起来的计数应该是 80000,但加起来只有 216。

我无法理解为什么会这样.. 谁能帮帮我吗。我哪里错了,要纠正什么。

我的需要基本上是为交易制定分析。

【问题讨论】:

    标签: php mongodb mapreduce aggregation-framework


    【解决方案1】:

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

    这是你发出的价值:

    this.amount
    

    这是你从 reduce 中返回的内容:

    return {total:total, count:count};
    

    为了让reduce在rereduce时正常工作(记住,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};
    

    The two most important rules of mapReduce in MongoDB:

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

    2. 结构 reduce 以便每个键可以调用零次、一次或多次

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

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

    【讨论】:

    • 附注在这两种情况下,您将返回类似于以下格式:{ _id:{name:"name", type:"txntype"}, total:Total, count: Count}(map/reduce 将具有 _id:{},value{ }) 但在聚合框架中,您可以根据需要使用 $project 步骤重命名字段。
    • 你知道如何使用 PHP 中的聚合函数吗..我正在从 PHP 应用程序访问 MongoDB..不确定如何从那里进行操作..
    • 它并不比 mapReduce 更难——按照这里的例子:php.net/manual/en/mongocollection.aggregate.php
    • 附注仅供参考,PHP 中有另一个帮助器从聚合中返回游标,与查找查询相同:php.net/manual/en/mongocollection.aggregatecursor.php 但您需要使用 2.6 mongodb 才能使用它。
    猜你喜欢
    • 2023-03-31
    • 2013-07-03
    • 2021-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 2013-01-04
    相关资源
    最近更新 更多