2

$update と $elemMatch を使用して、Level3 配列内の単一のドキュメント フィールドを更新することは可能ですか? この場合、位置演算子を複数回使用できないことに気づきました。歴史的に、これらのドキュメントはそれほど大きくないため、必要なより深い変更を加えて Level2 のネストされたドキュメントを変更しました。$elemMatch を使用して、Level3 配列内のターゲット ドキュメントの位置や Level2 内のドキュメントを含むドキュメントを知らなくても、Level3 配列ドキュメントを更新できる構文があることを願っています。

例:

db.collection.update({_id:'123', level2:{$elemMatch:{'level3.id':'bbb','level3.e1':'hij'}},{'level2.level3.createdDate':new Date()})

{
    _id:'123',
    f1:'abc',
    f2:'def',
    level2:[
        {_
            id:'aaa',
            e1:'hij',
            e2:'lmo'
            level3:[
                {
                    name:'foo',
                    type:'bar',
                    createdDate:'2013-3-28T05:18:00'
                }]
        },
        {_
            id:'bbb',
            e1:'hij',
            e2:'lmo'
            level3:[
                {
                    name:'foo2',
                    type:'bar2',
                    createdDate:'2013-3-28T05:19:00'
                }]
        }
    ]
}
4

1 に答える 1

1

ご指摘の理由により、現在、通常の更新操作を使用してこれを行う方法はありません。

現時点で使用できる唯一の回避策は、ドキュメントにバージョン管理を追加し、ドキュメントを読み取り、アプリケーションで変更する適切な要素を見つけ、それらの値を変更してからupdate、読み取りにバージョンを含む を使用することで、楽観的ロックを使用することです。ドキュメント (クエリと更新の間に他のスレッドがドキュメントを更新した場合、変更を上書きすることはありませんが、ドキュメントをリロードして再試行する必要があります。

バージョン管理戦略は、ドキュメント全体に基づく必要はありません。最初のレベルの配列要素をバージョン管理してから、関心のあるサブ配列だけを更新できます ($set を使用した更新を介して)。

于 2013-04-28T00:23:24.303 に答える