2013-06-24 2 views
5

모든 문서에서 "en"이라는 제목의 필드 이름을 "en-GB"로 바꿔야합니다.이 코드를 시도했지만 JavaScript 실행이 실패했습니다. RangeError : 최대 호출 스택 크기가 초과되었습니다. 문제는 경로를 모른 채 함수를 사용하여 하위 문서를 검색하는 것입니다.Mongodb 재귀 검색

remap = function (x) { 
    if (x.en){ 
     db.products.update({_id:x._id}, {$rename:{"en":"en-GB"}}, false, true); } 
for (var propt in x) { 
    if (Object.prototype.toString.call(x[propt]) === '[object Array]' || 
     Object.prototype.toString.call(x[propt]) === '[object Object]'){ 
     remap(x[propt]); 
    } 
} 

}

내가 대신 배열을 사용하여 큐에 추가하는 비슷한 작성하지만, 예 : "document.subdocument"로 하위 문서의 경로를 저장하고 실행하는 방법이 필요했다

다시 필드를 확인하는 기능을 통해.

+0

개체에 순환 참조가있을 수 있습니까? X는 Y를 가리키고, Y는 Z를 가리키고, Z는 X를 가리 킵니까? 스택 오버플로가 발생합니다. – Brandon

+0

'propt'의 값보다는'x [propt]'를 사용해야합니다.'x'의 속성의 이름 일뿐입니다. – WiredPrairie

답변

3

다음과 같이 시도해보십시오.

첫째, 단지 컬렉션의 모든 문서에 이름을 사용

db.products.update({}, {$rename:{"en":"en-GB"}}, false, true); 

는 그렇게 할 이유도없는 다시 매핑 기능을한다. 또한 사용 된 구문은 enen-GB으로 업데이트하여 모든 문서 (특정 문서 아님)를 업데이트한다는 의미입니다. 당신은 단지 하나의 특정 문서를 업데이트하고 싶다면

, 당신은 예를 들어 _id하여 문서를 지정해야 할 것 :

db.products.update({_id : x._id}, {$rename:{"en":"en-GB"}}, false, true); 

을 그리고, 각 문서의 모든 속성을 통해 루프로 다시 매핑 기능을 수정, 값을 잡고 유형을 확인하십시오.

var remap = function (x) { 
    for (var propt in x) { 
     var val = x[propt]; 
     var type = Object.prototype.toString.call(val); 
     if (type === '[object Array]' || type === '[object Object]') { 
      remap(val); 
     } 
    } 
}; 

다음과 같이 재귀 적으로 호출 할 수 있습니다. 이지만 하위 개체의 속성 이름이 변경되지 않습니다. 그보다 더 복잡한 경우에는 각각에 대해 전체 문서를 전달하고 재귀 적으로 유지 관리 한 다음 (문서 경로를 사용하여 "subobject.locale"과 같은 속성 경로를 사용하거나 문서 전체를 다시 저장) 문서의 모든 속성을 한 번에 업데이트해야합니다. 배열에서 객체를 제거하고 새로운 수정으로 동일한 색인에 다시 삽입해야하거나 배열 색인 지정자를 사용해야하므로 배열을 제 위치에서 수행하기가 더 어려울 수 있습니다. 전체 문서를 저장하면 모든 문서를 제 위치에서 수정할 수 있으므로 더 간단합니다.

솔직히 말해서, 나는이 시점에서 쉘이 아닌 당신이 선호하는 프로그래밍 언어를 사용하여 이것을 할 것입니다.

+0

"product.description"과 같은 하위 문서 경로를 함수를 통해 실행할 수있는 문자열로 저장할 수 있습니까? 같은 필드에 대해 모든 문서와 하위 문서를 모두 스캔 한 다음 이름을 바꿔야합니다. –

+0

프로그래밍 언어에 따라, 예. JavaScript 객체 일 뿐이라면 필요한 속성을 설정하기 만하면됩니다. – WiredPrairie