$[<identifier>]
項目一覧
定義
$[<identifier>]
フィルタリングされた位置演算子
$[<identifier>]
は、arrayFilters
条件に一致する配列要素をdb.collection.updateMany()
やdb.collection.findAndModify()
などの更新操作で識別します。arrayFilters
オプションと組み合わせて使用される場合、$[<identifier>]
演算子は次の形式になります。{ <update operator>: { "<array>.$[<identifier>]" : value } }, { arrayFilters: [ { <identifier>: <condition> } ] } ドキュメント内の
arrayFilters
条件に一致するすべての要素、またはクエリ条件に一致するドキュメントを更新するには、arrayFilters
オプションと組み合わせて使用します。 (例: )。db.collection.updateMany( { <query conditions> }, { <update operator>: { "<array>.$[<identifier>]" : value } }, { arrayFilters: [ { <identifier>: <condition> } ] } ) 注意
<identifier>
は小文字で始まり、含めることができるのは英数字のみです。
動作
MongoDB 5.0 以降、更新演算子では名前が文字列ベースのドキュメントフィールドを辞書順に処理します。数値名のフィールドは、数値順に処理されます。詳細については、「更新演算子の動作」を参照してください。
制限事項
arrayFilters
オプションには次のクエリ演算子を含めることはできません。
upsert
upsert 操作の結果が挿入になる場合、アップデートステートメントで $[<identifier>]
を使用するには、 query
に配列フィールドの正確な等価一致が含まれている必要があります。
例えば、次のアップサート操作では、更新ドキュメントで $[<identifier>]
を使用し、配列フィールドに完全等価一致の条件を指定します。
db.collection.updateOne( { myArray: [ 0, 1 ] }, { $set: { "myArray.$[element]": 2 } }, { arrayFilters: [ { element: 0 } ], upsert: true } )
そのようなドキュメントが存在しない場合は、この操作によって次のようなドキュメントが挿入されます。
{ "_id" : ObjectId(...), "myArray" : [ 2, 1 ] }
アップサート操作に正確な等価一致が含まれず、アップデートする一致するドキュメントが見つからない場合、アップサート操作はエラーになります。たとえば、アップデートする一致するドキュメントが見つからない場合、次の操作はエラーになります。
db.array.updateOne( { }, { $set: { "myArray.$[element]": 10 } }, { arrayFilters: [ { element: 9 } ], upsert: true } )
この操作では、次のようなエラーが返されます。
MongoServerError: The path 'myArray' must exist in the document in order to apply array updates.
ネストされた配列
フィルターされた位置演算子 $[<identifier>]
は、複数の配列およびネストされた配列を走査するクエリに使用できます。
例については、「 $[]
を使用した入れ子配列のアップデート 」を参照してください。
例
一致するすべての配列要素をアップデートする arrayFilters
students
コレクションを次のように作成します。
db.students.insertMany( [ { "_id" : 1, "grades" : [ 95, 92, 90 ] }, { "_id" : 2, "grades" : [ 98, 100, 102 ] }, { "_id" : 3, "grades" : [ 95, 110, 100 ] } ] )
grades
配列内の100
以上の全要素を更新するには、フィルタリングされた位置演算子$[<identifier>]
とarrayFilters
を組み合わせて使用します。
db.students.updateMany( { }, { $set: { "grades.$[element]" : 100 } }, { arrayFilters: [ { "element": { $gte: 100 } } ] } )
位置演算子 は、 $[<identifier>]
arrayFilters
で指定された条件に一致する配列フィールド内のすべての要素のプレースホルダーとして機能します。
操作後、students
コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "grades" : [ 95, 92, 90 ] } { "_id" : 2, "grades" : [ 98, 100, 100 ] } { "_id" : 3, "grades" : [ 95, 100, 100 ] }
配列内の に一致するすべてのドキュメントを更新arrayFilters
$[<identifier>]
演算子は、埋め込みドキュメントを含む配列の更新を容易にします。 埋め込みドキュメントのフィールドにアクセスするには、 を使用した ドット表記 $[<identifier>]
を使用します。
db.collection.updateMany( { <query selector> }, { <update operator>: { "array.$[<identifier>].field" : value } }, { arrayFilters: [ { <identifier>: <condition> } } ] } )
students2
コレクションを次のように作成します。
db.students2.insertMany( [ { "_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 } ] } ] )
grades
配列のすべての要素のうち、グレードが85
以上であるmean
フィールドの値を変更するには、位置指定の$[<identifier>]
演算子とarrayFilters
を使用します。
db.students2.updateMany( { }, { $set: { "grades.$[elem].mean" : 100 } }, { arrayFilters: [ { "elem.grade": { $gte: 85 } } ] } )
操作後、コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 100, "std" : 4 }, { "grade" : 85, "mean" : 100, "std" : 6 } ] } { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 100, "std" : 6 }, { "grade" : 87, "mean" : 100, "std" : 3 }, { "grade" : 85, "mean" : 100, "std" : 4 } ] }
複数の条件に一致するすべての配列要素をアップデートする
students3
コレクションを次のように作成します。
db.students3.insertMany( [ { "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 100, "std" : 4 }, { "grade" : 85, "mean" : 100, "std" : 6 } ] }, { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 100, "std" : 6 }, { "grade" : 87, "mean" : 100, "std" : 3 }, { "grade" : 85, "mean" : 100, "std" : 4 } ] } ] )
std
配列のすべての要素のうち、グレードがgrades
80
以上であり、かつstd
が5
以上である、 フィールドの値を変更するには、位置次のコマンドを使用します$[<identifier>]
演算子とarrayFilters
演算子:
db.students3.updateMany( { }, { $inc: { "grades.$[elem].std" : -1 } }, { arrayFilters: [ { "elem.grade": { $gte: 80 }, "elem.std": { $gte: 5 } } ] } )
操作後、コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 5 }, { "grade" : 85, "mean" : 100, "std" : 4 }, { "grade" : 85, "mean" : 100, "std" : 5 } ] } { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 100, "std" : 5 }, { "grade" : 87, "mean" : 100, "std" : 3 }, { "grade" : 85, "mean" : 100, "std" : 4 } ] }
否定演算子を使用して配列要素をアップデートする
alumni
コレクションを次のように作成します。
db.alumni.insertMany( [ { "_id": 1, "name": "Christine Franklin", "degrees": [ { "level": "Master" }, { "level": "Bachelor" } ], }, { "_id": 2, "name": "Reyansh Sengupta", "degrees": [ { "level": "Bachelor" } ], } ] )
"level": "Bachelor"
を持たないdegrees
配列内のすべての要素を変更するには、位置指定$[<identifier>]
操作と$ne
クエリ演算子を使用します。
db.alumni.updateMany( { }, { $set : { "degrees.$[degree].gradcampaign" : 1 } }, { arrayFilters : [ {"degree.level" : { $ne: "Bachelor" } } ] } )
操作後、コレクションには次のドキュメントが含まれます。
{ _id: 1, name: 'Christine Franklin', degrees: [ { level: 'Master', gradcampaign: 1 }, { level: 'Bachelor' } ] }, { _id: 2, name: 'Reyansh Sengupta', degrees: [ { level: 'Bachelor' } ] }
ネストされた配列を合わせて更新 $[]
$[<identifier>]
フィルター位置演算子は、$[]
all 位置演算子と組み合わせて、ネストされた配列をアップデートするために使用できます。
次のドキュメントで、コレクション students4
を作成します。
db.students4.insertOne( { "_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 ] }, ] } )
以下は、関連付けられている grades.type
フィールドが quiz
の場合、ネストされた grades.questions
配列内の 8
以上の値をアップデートします。
db.students4.updateMany( {}, { $inc: { "grades.$[t].questions.$[score]": 2 } }, { arrayFilters: [ { "t.type": "quiz" }, { "score": { $gte: 8 } } ] } )
注意
配列識別子の周囲にスペースを含めないでください。前の例えで grades.$[ t ].questions.$[ score ]
を使用すると、例は失敗します。
操作後、コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "grades" : [ { "type" : "quiz", "questions" : [ 12, 10, 5 ] }, { "type" : "quiz", "questions" : [ 10, 11, 6 ] }, { "type" : "hw", "questions" : [ 5, 4, 3 ] }, { "type" : "exam", "questions" : [ 25, 10, 23, 0 ] } ] }
type
に関係なく、ネストされたgrades.questions
配列内で8
以上のすべての値をアップデートするには、
db.students4.updateMany( {}, { $inc: { "grades.$[].questions.$[score]": 2 } }, { arrayFilters: [ { "score": { $gte: 8 } } ] } )