6

ドキュメントのコレクションだけでなく、サブドキュメントも検索し、出現するたびに「en」というタイトルのフィールドの名前を「en-GB」に変更する必要があります。このコードを試しましたが、JavaScript の実行に失敗しました: RangeError: Maximum call stack size超過エラー。問題は、パスを知らずに関数を使用してサブドキュメントを検索することです。

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」などのサブドキュメントパスを保存し、関数を再度実行してフィールドを確認する方法が必要です。

4

1 に答える 1

3

以下のようなものを試すことができます。

まず、コレクション内のすべてのドキュメントで rename を使用します。

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

リマップ関数でそれを行う理由はありません。さらに、使用した構文は、に更新することにより、すべてのドキュメント (特定のドキュメントではない) を更新することを意味enen-GBます。

特定のドキュメントを 1 つだけ更新する場合は、次のようにドキュメントを指定する必要があります_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"か、ドキュメント全体を再保存します)。配列内のオブジェクトを削除し、新しい変更を加えて同じインデックスに再挿入する (または配列インデックス指定子を使用する) 必要があるため、配列はその場で行うのがより難しい場合があります。ドキュメント全体を保存すると、それらをすべてその場で変更でき、簡単になります。

正直なところ、現時点では、シェルからではなく、お気に入りのプログラミング言語を使用してこれを行います。

于 2013-06-24T12:30:25.070 に答える