mongodb mapreduce脚本来计算总订单失败

时间:2015-09-16 08:22:39

标签: javascript mongodb

我是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 } }

有人可以告诉我出了什么问题。 的问候,

1 个答案:

答案 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;
}