我有这样的地图缩小:
图:
function() {
emit(this.username, {sent:this.sent, received:this.received});
}
减少
function(key, values) {
var result = {sent: 0, received: 0, entries:0};
values.forEach(function (value) {
result.sent += value.sent;
result.received += value.received;
result.entries += 1;
});
return result;
}
我一直在监视结果图中处理的条目数量,如您所见。我发现访问记录的数量远低于我应该记录的数量。
对于我的特定数据集,输出如下:
[{u'_id':u'1743',u'value':{u'received':1406545.0,u'sent':26251138.0,u'entries':316.0}}]
当我使用查询选项运行地图缩小时,指定用户名和日期范围。
如果我使用db.collection.find()执行相同的查询,则计数方式不同:
> db.entire_database.find({username: '1743', time : { $lte: ISODate('2011-08-12 12:40:00'), $gte: ISODate('2011-08-12 08:40:00') }}).count()
1915
完整地图缩减查询是这样的:
db.entire_database.mapReduce(m, r, {out: 'myoutput', query: { username: '1743', time : { $lte: ISODate('2011-08-12 12:40:00'), $gte: ISODate('2011-08-12 08:40:00') } } })
所以基本上,我不确定为什么伯爵是如此根本不同?为什么find()给我1915,但地图缩小是316?
答案 0 :(得分:4)
您的map
函数需要发出一个与reduce
函数具有相同形式的对象(即它应该将entries
字段设置为1)。您可以阅读有关此here的更多信息。
基本上,传递给reduce
函数的值不一定是map
发出的原始输出。 reduce
函数不是被调用一次,而是在由map
生成的值的“组”上多次调用,然后将结果再次组合在一起进一步调用reduce
函数。这使得MapReduce可以水平扩展,因为任何一组发射值都可以在以后组合之前以任何顺序排列到任何服务器。
所以我会稍微重构你的功能:
图:
function() {
emit(this.username, {sent:this.sent, received:this.received, entries : 1});
}
减少
function(key, values) {
var result = {sent: 0, received: 0, entries:0};
values.forEach(function (value) {
result.sent += value.sent;
result.received += value.received;
result.entries += value.entries;
});
return result;
}