1

これが私のMap、Reduce、finalize関数です。キーに一致するレコードは4つあり、mapreduceがより少ないデータ(100秒)で呼び出されると結果は正しくなりますが、mapreduceがより多くのデータ(1000秒)で呼び出されると常に2としてカウントされます。削減機能を確認しましたが、より大きなデータに対して内部的に複数回呼び出されている場合でも、正しいように見えます。これは奇妙になりつつあり、私は長い時間を費やしましたが、それでも正しく理解できませんでした。

var map1 = function(){
    var mapPosCnt = 0, mapPosSum = 0, mapZeroCnt = 0;
    if (isNumber(this.val1)){
        if(this.val1.toPrecision(10)  > 0.0000000000){
            mapPosCnt = 1;
            mapPosSum = this.val1;
        }else{
            mapZeroCnt = 1;
        }
    }else{
        mapPosCnt = 0, mapPosSum = 0, mapZeroCnt = 0;
    }
    emit({key1: this.key1, key2: this.key2+'', val1: 'val1'}
        ,{key1: this.key1, key2: this.key2+'', posCnt: mapPosCnt, posSum: mapPosSum, posAvg: 0, zeroCnt: mapZeroCnt, val1: this.val1});
}
var reduce1 = function(key, values){
    var retval = {key1: key.CE, key2: key.key2, posCnt: 0, posSum: 0, posAvg: 0, zeroCnt: 0, val1: 0};
    values.forEach(function(value){
        if (isNumber(value.val1)){
            if(value.val1.toPrecision(10)  > 0.0000000000){
                retval.posCnt += 1;
                retval.posSum += value.val1;
            }else{
                retval.zeroCnt += 1;
            }
        }
    })
    return retval;
}
var finalize1 = function(key, value){
    value.key2 = value.key2.toString();
    if(value.posCnt > 0){
        value.posSum = Math.round(value.posSum * Math.pow(10, 6)) / Math.pow(10, 6);
        value.posAvg = Math.round((value.posSum/value.posCnt) * Math.pow(10, 6)) / Math.pow(10, 6);
    }
    return value;
}
collection1.mapReduce(map1, reduce1, {out: {merge: 'collection2'}, finalize: finalize1}, function(err, collection){});
4

1 に答える 1

1

それをテストするためのドキュメントがなければ、私は少し推測していますが、いくつかの問題を見ることができます:

  1. 発行/削減された値には、キー フィールドを含めないでください。したがって、発行された値は次のようになります。 { posCnt: mapPosCnt, posSum: mapPosSum, zeroCnt: mapZeroCnt }
  2. reduce 関数は、あなたが行っているように発行ロジックを再適用しようとするべきではなく、値を合計して同じキーで値を集約する必要があります。

したがってreduce1、次のようになります。

var reduce1 = function(key, values){
    var retval = { posCnt: 0, posSum: 0, zeroCnt: 0 };
    values.forEach(function(value){
        retval.posCnt += value.posCnt;
        retval.posSum += value.posSum;
        retval.zeroCnt += value.zeroCnt;
    });
    return retval;
};
于 2013-02-25T15:56:18.390 に答える