0

MapReduce 集計を 2 回使用して、月ごとの一意のユーザー数を取得しようとしました。

最初の 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 } }

2 番目の MR 関数は小さなデータ セットでうまく機能しますが、クエリが 100 レコードを超えると、間違った結果が得られ、一部の値が NaN になります。

デバッグ ログには、v.payment、v.count_user などの Reduce 関数の値が undefine になったことが示されています。

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

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,
}

これは 2 番目の 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"}
    }
)
4

1 に答える 1

2

Reduce 関数のサブドキュメントは、Map 関数のサブドキュメントと同じ形式を使用する必要があります。したがって、解決策は次のとおりです。

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;
},
于 2013-10-04T20:51:17.297 に答える