2014-09-02 4 views
1

일부 필드가 숫자이거나 NaN 값을 가질 수있는 일관성없는 문서를 MongoDB 컬렉션에서 처리해야합니다. $ inc로 업데이트해야합니다. 하지만 NaN 값 $ inc가없는 것처럼 보입니다. 원자 적 문서 갱신에 사용할 수있는 옵션은 무엇입니까?

+0

값이 NaN 인 경우 예상되는 동작은 무엇입니까? 0으로 간주하고 증가시켜야합니까?숫자가 아닌 필드의 값에 대한 샘플 데이터를 제공하십시오. – BatScream

답변

3

글쎄, 이것은 두 가지 논리적 결론을 이끌어내는 것으로 보입니다. 첫 번째로 필드에 NaN 값이 있으면 식별 방법은 무엇입니까? 다음 예제를 고려의 컬렉션 "nantest"

{ "_id" : ObjectId("54055993b145d1c015a1ad41"), "n" : NaN } 
{ "_id" : ObjectId("540559e8b145d1c015a1ad42"), "n" : Infinity } 
{ "_id" : ObjectId("54055b59b145d1c015a1ad43"), "n" : 1 } 
{ "_id" : ObjectId("54055ea1b145d1c015a1ad44"), "n" : -Infinity } 

그래서 모두 NaNInfinity 또는 -Infinity 어떻게 든 데이터에 등장했다 "비 숫자"의 대표를 호출 할 수 있습니다. 해당 필드가 설정된 방식으로 이러한 문서를 찾는 가장 좋은 방법은 연산자를 JavaScript 평가 쿼리 조건에 사용하는 것입니다. 효율적이지는 않지만 가지고있는 것 :

db.nantest.find({ 
    "$where": "return isNaN(this.n) || Math.abs(this.n) == Infinity" 
}) 

이렇게하면 문제가되는 데이터를 찾는 방법이 제공됩니다. 여기에서 농구를 뛰어 넘을 수 있고, 이것이 발생했을 때 증분하기 전에 0으로 리셋 할 것입니다. 기본적으로 값이 정확하면 첫 번째 것이 업데이트 할 문서와 일치하지 않을 것입니다.

db.nantest.update(
    { "$where": "return isNaN(this.n) || Math.abs(this.n) == Infinity" }, 
    { "$set": { "n": 0 } } 
); 
db.nantest.update(
    { }, 
    { "$inc": { "n": 1 } } 
); 

하지만 실제로 보면, 왜 데이터를 패치 할 수있을 때 코드를 패치해야할까요? 그래서 논리적 인 것은 결국 한 성명에서 표준 리셋 번호로 모든 Nan 가능성이 Infinity 값을 업데이트한다 결론 :

db.nantest.update(
    { "$where": "return isNaN(this.n) || Math.abs(this.n) == Infinity" }, 
    { "$set": { "n": 0 } }, 
    { "multi": true } 
); 

중 하나를 실행 문 다음 당신은 당신의 코드와 단순히 프로세스를 변경할 필요가 없습니다 보통 예상대로 증가합니다.

당신의 문제가 존재하는 Nan 값 필드를 검사 한 후,이를 해결이 맵리 듀스 프로세스의 라인을 따라 뭔가를 고려하는 업데이트를 호출하기 위해이있는 필드를 아는 경우 :

db.nantest.mapReduce(
    function() { 

    var doc = this; 
    delete doc._id; 

    Object.keys(doc).forEach(function(key) { 
     if (isNaN(doc[key]) || Math.abs(doc[key]) == Infinity) 
     emit(key, 1); 
    }); 

    }, 
    function (key,values) { 
    return Array.sum(values); 
    }, 
    { "out": { "inline": 1 } } 
) 

를하는 당신 더 많은 중첩 된 문서를 위해 약간의 복잡성을 추가해야 할 수도 있지만, 이것은 잘못된 문구를 포함 할 수있는 필드를 알려줌으로써이를 수정하기위한 업데이트 문을 생성 할 수 있습니다.

그것은 오히려 당신이 "해야"이 맞게 코드를 굽힘 것보다 일을 보일 수있을 것입니다 :

  1. 는 숫자가 표시되고 그 문제를 해결하기 위해 원인이되는 소스를 찾을 수 있습니다.

  2. 는 필드 또는 한 번에 데이터를 해결하기 위해

  3. 프로세스 일회성 업데이트 문이 값을 포함하는 필드를 확인합니다.

코드로 인한 복잡함과 문제의 "원본"과 도입 된 데이터 손상의 "결과"가 모두 수정되었습니다.