我是新的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的两个最重要的规则:
以与reduce函数返回的完全相同的格式发出值
结构减少,以便每个键可以调用零,一次或多次
请注意,使用聚合框架可以更高效、更快地执行相同的聚合,如下所示:
db.collection.aggregate( {$group:
{ _id : {name: "$name", type: "$txnType"},
total: {$sum: "$amount"},
count: {$sum: 1}
}
}