2012-05-23 3 views
1

MongoDB 데이터베이스에는 모든 사용자 계정의 목록이 포함되어 있습니다. 여기에서 새로운 등록에는 계정 문서의 'created_at'필드가 생성 당시의 날짜와 시간과 함께 있습니다.두 개의 겉으로보기에 동일한 MapReduce 함수의 수수께끼 동작

얼마나 많은 신규 등록이 있었는지 확인하려면 MapReduce 쿼리를 사용하여이를 찾아야합니다.

db.accounts.mapReduce(
    function() { 
     var date = this.created_at.toLocaleDateString(); 
     emit(date, 1); 
    }, 
    function(key, values) { 
     return values.length; 
    }, 
    { out: "output" }) 

위의 첫 번째 시도가있었습니다. 각 등록에 대해 해당 날짜의 값은 1입니다. 각 배열의 길이는 그 날에 얼마나 많은 등록이 있었는지를 결정하는 데 사용됩니다.

그러나 결과가 거의 정확했지만 주목할만한 부정확성이있었습니다. 예를 들어 첫날은 실제 수치가 훨씬 더 높을 때 우리에게 두 자릿수의 가치를 부여했습니다. 동일한 데이터에서 작동 함에도 불구하고 map reduce 함수를 두 번째 실행 한 후 일부 값이 변경되었습니다.

우리는 대신에, 단지 1 's의 구성 때문에 array.length에 동일해야 기억 배열의 값을 (요약하는 기능을 변경했습니다.

db.accounts.mapReduce(
    function() { 
     var date = this.created_at.toLocaleDateString(); 
     emit(date, 1); 
    }, 
    function(key, values) { 
     var sum = 0; 
     for(var i = 0; i < values.length; i++) { 
      sum += values[i]; 
     }; 
     return sum; 
    }, 
    { out: "output" }) 

을 놀랍게도,이 준 잘못된 예전의 모든 날짜에 대한 올바른 결과. 의도 한대로 첫 번째지도가 작동하지 않았다 감소 이유

사람이 알고 있나요?

답변

2

함께 방출-ED 값에 대한 여러 번 호출 할 수 감소 나중에 호출은 이전 호출의 출력을 전달하여 감소시킵니다. 배열의 길이 만 보면 부분적으로 집계 된 데이터를 볼 수 있다는 사실을 놓치게됩니다. 값을 합산하면 이전 집계가 누적되어 원하는 결과를 얻을 수 있습니다.

+0

D' oh 물론! 당황스럽게 단순한 일이 될 거라는 것을 알았습니다. 고마워! – Dave

관련 문제