我是PHP和mongo DB的新手 我有一个80000条记录的数据集,这是一个本地部署。
我的数据结构很简单:
(
[_id] => MongoId Object
(
[$id] => 53c146aebc7d867d058b94b3
)
[name] => Mark
[txnType] => Borrowed
[amount] => 5876
)
我正在运行Map Reduce Job,定义如下:
$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。
我无法理解为什么会这样。 谁能帮帮我吗。我哪里出错了,纠正什么。
我的需要是基本上为交易制定分析。
答案 0 :(得分:1)
问题是您的emit输出的格式与reduce相同。
这是你为价值所发出的:
this.amount
以下是您从reduce返回的内容:
return {total:total, count:count};
为了使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};
The two most important rules of mapReduce in MongoDB:
以与reduce函数返回完全相同的格式发出值
结构减少,以便每个键可以被称为零,一次或多次
请注意,您可以使用聚合框架更高效,更快地执行相同的聚合,如下所示:
db.collection.aggregate( {$group:
{ _id : {name: "$name", type: "$txnType"},
total: {$sum: "$amount"},
count: {$sum: 1}
}
}