简体   繁体   English

在mongodb MapReduce中获取未定义的值

[英]get undefined value in mongodb MapReduce

I tried to use twice MapReduce aggregation to get unique user number per month. 我尝试使用两次MapReduce聚合来获取每月唯一的用户数。

The first MR function work out a mr_buyer_payment collection, like this: 第一个MR函数计算出mr_buyer_payment集合,如下所示:

{ "_id" : { "u" : "01329f19-27b0-435b-9ca1-450984024a31", "tid" : ISODate("2013-09-01T00:00:00Z") }, "value" : { "payment" : 38, "count_pay" : 1 } }
{ "_id" : { "u" : "264dd104-b934-490b-988e-5822fd7970f6", "tid" : ISODate("2013-09-01T00:00:00Z") }, "value" : { "payment" : 4.99, "count_pay" : 1 } }
{ "_id" : { "u" : "27bb8f72-a13e-4676-862c-02f41fea1bc0", "tid" : ISODate("2013-09-01T00:00:00Z") }, "value" : { "payment" : 11.98, "count_pay" : 2 } }

The second MR function works well with small data set , but when query grows more than 100 records, it gets wrong result , some value is NaN. 第二个MR函数适用于较小的数据集,但是当查询增长到100条以上的记录时,它将得到错误的结果,某些值为NaN。

The debug log shows some value in Reduce function like v.payment, v.count_user became undefine. 调试日志在Reduce函数中显示了一些值,例如v.payment,v.count_user变为未定义。

date:Sun Jun 30 2013 17:00:00 GMT-0700 (PDT)  value:undefined / 162 / undefined

And the MR result info is wired: 并连接了MR结果信息:

{
    "result" : "mr_buyer_all",
    "timeMillis" : 29,
    "counts" : {
        "input" : 167,
        "emit" : 167,
        "reduce" : 6,  // it should be 3, as same as "output" number
        "output" : 3
    },
    "ok" : 1,
}

This is 2nd MR function: 这是第二MR功能:

db.mr_buyer_payment.mapReduce(
    function(){
        var key = this._id.tid;
        var value = {
            payment:this.value.payment,
            count_pay:this.value.count_pay,
            count_user:1
        };
        if (value.count_pay>0)
        {
            print("date:"+key+"  u:"+this._id.u+"value:"+value.payment+" / "+value.count_pay+" / "+value.count_user);
            emit(key,value);
        }
    },
    function(key,values){
        var result = {revenue:0,count_pay:0,user:0};
        values.forEach(function(v){
            if (!v.count_user)
            {
                print("date:"+key+"  "+"value:"+v.payment+" / "+v.count_pay+" / "+v.count_user);
            } else
            {
                result.revenue += v.payment;
                result.count_pay += v.count_pay;
                result.user += v.count_user;
            }

        });
        return result;
    },
    {
        out:{replace:"mr_buyer_all"}
    }
)

The sub-document in Reduce function should use same format as one in Map function. Reduce函数中的子文档应使用与Map函数中相同的格式。 So the solution is : 所以解决方案是:

function(key,values){
    // the following key must be as same as the object in map
    var r = {payment:0,count_pay:0,count_user:0}
    values.forEach(function(v){
        r.payment += v.payment;
        r.count_pay += v.count_pay;
        r.count_user += v.count_user;
    });
    return r;
},

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM