mongodb mapreduce-缺少数据

mongodb mapreduce-缺少数据,mongodb,mapreduce,Mongodb,Mapreduce,这是我的Map、Reduce和finalize函数。有4条记录与键匹配,当使用较少的数据(100秒)调用mapreduce时,结果正确,但当使用较多的数据(1000秒)调用mapreduce时,计数始终为2。我检查了Reduce函数,在我看来,它似乎是正确的,即使它在内部被多次调用以获取更大的数据。这是越来越奇怪,我花了很长时间,但仍然不能得到它的权利 var map1 = function(){ var mapPosCnt = 0, mapPosSum = 0, mapZeroCnt

这是我的Map、Reduce和finalize函数。有4条记录与键匹配,当使用较少的数据(100秒)调用mapreduce时,结果正确,但当使用较多的数据(1000秒)调用mapreduce时,计数始终为2。我检查了Reduce函数,在我看来,它似乎是正确的,即使它在内部被多次调用以获取更大的数据。这是越来越奇怪,我花了很长时间,但仍然不能得到它的权利

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){});

没有文档进行测试,我有点猜测,但我可以看到几个问题:

  • 发出/减少的值不应包括关键字段。因此,您发出的值应该如下所示:
    {posCnt:mapPosCnt,posSum:mapposum,zeroCnt:mapZeroCnt}
  • reduce函数不应该像您正在做的那样尝试重新应用emit逻辑,而是应该通过对值求和来聚合具有相同键的值
  • 因此
    reduce1
    应该如下所示:

    var reduce1=函数(键、值){
    var-retval={posCnt:0,posSum:0,zeroCnt:0};
    values.forEach(函数(值){
    retval.posCnt+=value.posCnt;
    retval.posSum+=value.posSum;
    retval.zeroCnt+=value.zeroCnt;
    });
    返回返回;
    };
    
    如果没有文档进行测试,我有点猜测,但我可以看到几个问题:

  • 发出/减少的值不应包括关键字段。因此,您发出的值应该如下所示:
    {posCnt:mapPosCnt,posSum:mapposum,zeroCnt:mapZeroCnt}
  • reduce函数不应该像您正在做的那样尝试重新应用emit逻辑,而是应该通过对值求和来聚合具有相同键的值
  • 因此
    reduce1
    应该如下所示:

    var reduce1=函数(键、值){
    var-retval={posCnt:0,posSum:0,zeroCnt:0};
    values.forEach(函数(值){
    retval.posCnt+=value.posCnt;
    retval.posSum+=value.posSum;
    retval.zeroCnt+=value.zeroCnt;
    });
    返回返回;
    };
    
    非常感谢Johnny;修复您提到的两个问题解决了我所面临的随机丢失数据的问题。很抱歉反应太晚,因为我整个星期都在做不同的任务,只是在做这个。非常感谢Johnny;修复您提到的两个问题解决了我所面临的随机丢失数据的问题。很抱歉反应太晚,因为我整个星期都在做不同的任务,只是在做这个。