$[]
定義
$[]
全位置演算子
$[]
は、指定された配列フィールドのすべての要素を更新演算子によって変更する必要があることを示します。$[]
演算子は次のような形をとります。{ <update operator>: { "<array>.$[]" : value } } 更新操作で使用します。
db.collection.updateOne()
およびdb.collection.findAndModify()
は、クエリ条件に一致するドキュメントのすべての配列要素を変更します。例えば:db.collection.updateOne( { <query conditions> }, { <update operator>: { "<array>.$[]" : value } } ) 例については、「 配列内のすべての要素の更新」を参照してください。
動作
MongoDB 5.0 以降、更新演算子では名前が文字列ベースのドキュメントフィールドを辞書順に処理します。数値名のフィールドは、数値順に処理されます。詳細については、「更新演算子の動作」を参照してください。
upsert
アップサート操作の結果が挿入になる場合、更新ステートメントで$[]
位置演算子を使用するには、 query
に配列フィールドの完全な等価一致が含まれている必要があります。
例えば、次のアップサート操作では、更新ドキュメントで $[]
を使用し、配列フィールドに完全等価一致の条件を指定します。
db.collection.updateOne( { myArray: [ 5, 8 ] }, { $set: { "myArray.$[]": 10 } }, { upsert: true } )
該当するドキュメントが存在しない場合は、この操作によって次のドキュメントが挿入されます。
{ "_id" : ObjectId(...), "myArray" : [ 10, 10 ] }
アップサート操作に完全な等価一致が含まれず、アップデートする一致するドキュメントが見つからない場合、アップサート操作はエラーになります。
たとえば、アップデートする一致するドキュメントが見つからない場合、次の操作はエラーになります。
db.emptyCollection.updateOne( { }, { $set: { "myArray.$[]": 10 } }, { upsert: true } ) db.emptyCollection.updateOne( { myArray: 5 }, { $set: { "myArray.$[]": 10 } }, { upsert: true } )
ネストされた配列
$[]
演算子は、複数の配列やネストされた配列を走査するクエリに使用できます。
例
配列内のすべての要素のアップデート
students
コレクションを次のように作成します。
db.students.insertMany( [ { "_id" : 1, "grades" : [ 85, 82, 80 ] }, { "_id" : 2, "grades" : [ 88, 90, 92 ] }, { "_id" : 3, "grades" : [ 85, 100, 90 ] } ] )
コレクション内のすべてのドキュメントのgrades
配列内のすべての要素を10
ずつ増やすには、全位置演算子$[]
を使用します。
db.students.updateMany( { }, { $inc: { "grades.$[]": 10 } }, )
全位置演算子$[]
は、配列フィールド内のすべての要素のプレースホルダーとして機能します。
操作後、students
コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "grades" : [ 95, 92, 90 ] } { "_id" : 2, "grades" : [ 98, 100, 102 ] } { "_id" : 3, "grades" : [ 95, 110, 100 ] }
配列内のすべてのドキュメントを更新
$[]
位置演算子は、埋め込みドキュメントを含む配列のアップデートを容易にします。埋め込みドキュメントのフィールドにアクセスするには、$[]
演算子を使用したドット表記を使用します。
db.collection.updateOne( { <query selector> }, { <update operator>: { "array.$[].field" : value } } )
students2
コレクションを次のように作成します。
db.students2.insertMany( [ { "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 8 }, { "grade" : 85, "mean" : 90, "std" : 6 }, { "grade" : 85, "mean" : 85, "std" : 8 } ] }, { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 75, "std" : 8 }, { "grade" : 87, "mean" : 90, "std" : 5 }, { "grade" : 85, "mean" : 85, "std" : 6 } ] } ] )
grades
配列内のすべての要素のstd
フィールドの値を変更するには、位置オペレーター$[]
を使用します。
db.students2.updateMany( { }, { $inc: { "grades.$[].std" : -2 } }, )
操作後、コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" : 85, "std" : 6 } ] } { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 75, "std" : 6 }, { "grade" : 87, "mean" : 90, "std" : 3 }, { "grade" : 85, "mean" : 85, "std" : 4 } ] }
否定クエリ演算子を使用して指定された配列を更新
results
コレクションを次のように作成します。
db.results.insertMany( [ { "_id" : 1, "grades" : [ 85, 82, 80 ] }, { "_id" : 2, "grades" : [ 88, 90, 92 ] }, { "_id" : 3, "grades" : [ 85, 100, 90 ] } ] )
grades
配列内の値100
を持つドキュメントを除くすべてのドキュメントのgrades
配列内のすべての要素を10
増分するには、すべての位置演算子$[]
を使用します。
db.results.updateMany( { "grades" : { $ne: 100 } }, { $inc: { "grades.$[]": 10 } }, )
全位置演算子$[]
は、配列フィールド内のすべての要素のプレースホルダーとして機能します。
操作後、students
コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "grades" : [ 95, 92, 90 ] } { "_id" : 2, "grades" : [ 98, 100, 102 ] } { "_id" : 3, "grades" : [ 85, 100, 90 ] }
ネストされた配列を合わせて更新 $[<identifier>]
$[]
演算子をフィルター $[<identifier>]
位置演算子と組み合わせて使用すると、ネストされた配列を更新できます。
次のドキュメントを使用してコレクション students3
を作成します。
db.students3.insertMany( [ { "_id" : 1, "grades" : [ { type: "quiz", questions: [ 10, 8, 5 ] }, { type: "quiz", questions: [ 8, 9, 6 ] }, { type: "hw", questions: [ 5, 4, 3 ] }, { type: "exam", questions: [ 25, 10, 23, 0 ] }, ] } ] )
type
に関係なく、ネストされたgrades.questions
配列内で8
以上のすべての値をアップデートするには、
db.students3.updateMany( {}, { $inc: { "grades.$[].questions.$[score]": 2 } }, { arrayFilters: [ { "score": { $gte: 8 } } ] } )
アップデートされたドキュメントは、次のようになります。
{ _id: 1, grades: [ { type: 'quiz', questions: [ 12, 10, 5 ] }, { type: 'quiz', questions: [ 10, 11, 6 ] }, { type: 'hw', questions: [ 5, 4, 3 ] }, { type: 'exam', questions: [ 27, 12, 25, 0 ] } ] }