我是mongodb的新手,我计划从SQL迁移到noSQL。我有很多存储过程,我认为mapReduce是等同的"在noSQL世界。 我开始使用js脚本试图按客户计算订单,但它会给出错误的结果。 脚本是:
db = connect("localhost:27017/pgi");
for(i=0;i<1000;i++){
db.orders.insert(
{
"cust_id" : 1,
"total" : 100,
});
}
for(i=0;i<1000;i++){
db.orders.insert(
{
"cust_id" : 2,
"total" : 100,
});
}
var res = db.orders.find({cust_id : 1});
print("Total Orders for customer 1:" + res.count());
var res = db.orders.find({cust_id : 2});
print("Total Orders for customer 2:" + res.count());
//map reduce
var map = function(){
emit(this.cust_id, 1);
}
var reduce = function(key, values){
var c = 0;
for (index in values) {
c += 1;
}
return {cust_id : key, count: c};
}
var res = db.orders.mapReduce(
map,
reduce,
{
out : {inline : 1}
}
);
res.find({}).forEach(function(item){
printjson(item);
});
每个客户的预期输出为1000,但我得到了这个:
connecting to: test
connecting to: localhost:27017/pgi
Total Orders for customer 1:1000
Total Orders for customer 2:1000
{ "_id" : 1, "value" : { "cust_id" : 1, "count" : 101 } }
{ "_id" : 2, "value" : { "cust_id" : 2, "count" : 101 } }
有人可以告诉我出了什么问题。 的问候,
答案 0 :(得分:1)
使用MapReduce,减速器输出的格式与映射器输出值的格式相同,因为reducer可能会为同一个键运行多次。此外,reducer不需要输出键,只需在输入数组上执行任何操作后输出结果值。
因此,在您的情况下,映射器看起来对于客户计数订单是正确的,但是reducer应该只输出总计数而不是生成带有密钥和计数的Object。
此外,reducer需要将每个index
的值相加,而不是递增1,以处理它在reduce函数的先前调用的输出上运行的情况。
var reduce = function(key, values){
var c = 0;
for (var index in values) {
c += values[index];
}
return c;
}