2013-02-25 3 views
1

Вот моя карта, уменьшите и завершите работу. Есть 4 записи, соответствующие ключу, и результат приходит правильно, когда mapreduce вызывается с меньшим количеством данных (100 с), но при условии, что число count равно 2, когда вызывается mapreduce с большим количеством данных (несколько тысяч). Я проверил функцию «Уменьшить», и мне кажется, что она правильная, даже если она многократно вызывается для больших данных. Это становится странным, и я трачу много часов и все еще не могу понять.mongodb mapreduce - отсутствует данные

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

ответ

1

Без Документов, чтобы проверить это, я предполагаю, немного, но я могу видеть пару вопросов:

  1. излучаемые/уменьшенные значения не должны включать в себя ключевые поля. Таким образом, ваше испущенное значение должно выглядеть следующим образом: { posCnt: mapPosCnt, posSum: mapPosSum, zeroCnt: mapZeroCnt }
  2. Функция уменьшения не должна пытаться повторно применять испускаемую логику, как вы делаете, а должна быть агрегировать значения с одним и тем же ключом, суммируя их значения.

Так 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; 
}; 
+0

большое спасибо Джонни; исправление 2 проблем, о которых вы говорили, решило случайную проблему с данными, с которыми я столкнулся. Извините за поздний ответ, так как всю неделю я занимался различными задачами и просто работал над этим. – user1549605

Смежные вопросы