定義
$位置演算子
$は、配列内の要素の位置を明示的に指定せずに、更新する配列内の要素を識別します。注意
曖昧さ回避
読み取り操作から配列要素をプロジェクションするか、または返すには、代わりに「
$プロジェクション演算子」を参照してください。配列内のすべての要素をアップデートするには、代わりにすべての位置演算子
$[]を参照してください。1 つまたは複数の配列フィルター条件に一致するすべての要素を更新するには、
$[<identifier>]の代わりにフィルタリングされた位置演算子を参照してください。
互換性
次の環境でホストされる配置では、位置オペレーター$を使用できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
構文
位置演算子 $ の形式は次のとおりです。
{ "<array>.$" : value }
更新操作で使用する場合、db.collection.updateOne()とdb.collection.findAndModify() 、
位置演算子
$はquery documentに一致する最初の要素のプレースホルダーとして機能し、arrayフィールドはquery documentの一部として出現する必要があります。
以下に例を挙げます。
db.collection.updateOne( { <array>: value ... }, { <update operator>: { "<array>.$" : value } } )
動作
MongoDB 5.0 以降、更新演算子では名前が文字列ベースのドキュメントフィールドを辞書順に処理します。数値名のフィールドは、数値順に処理されます。詳細については、「更新演算子の動作」を参照してください。
upsert
アップサート操作では $ 演算子を使用しないでください。アップデート クエリが既存のドキュメントと一致しない場合、$ 演算子には一致する配列要素が必要であるため、アップサートは失敗します。
ネストされた配列
位置演算子 $ は、$ プレースホルダーの置換が単一の値であるため、複数の配列を走査するクエリ(他の配列内にネストされた配列を走査するクエリなど)には使用できません
設定解除
$unset演算子とともに使用した場合、位置指定の$演算子は一致する要素を配列から削除せず、それをnullに設定します。
除外
クエリが$ne 、 $not 、 $ninなどの否定演算子を使用して配列と一致する場合、位置演算子を使用してこの配列の値を更新することはできません。
ただし、クエリの否定部分が$elemMatch式内にある場合は、位置演算子を使用したこのフィールドの更新が可能です。
複数の配列の一致
位置更新演算子 $ は、複数の配列フィールドをフィルタリングするときにあいまいな動作をします。
サーバーがアップデート メソッドを実行する際は、まずクエリを実行してアップデートするドキュメントを決定します。 更新で複数の配列フィールドのドキュメントがフィルタリングされる場合、位置指定の$更新演算子に対する後続の呼び出しでは、配列内の必要な位置が必ずしも更新されるわけではありません。
詳細については、例を参照してください。
例
配列内の値を更新
次のドキュメントを使用してコレクション students を作成します。
db.students.insertMany( [ { "_id" : 1, "grades" : [ 85, 80, 80 ] }, { "_id" : 2, "grades" : [ 88, 90, 92 ] }, { "_id" : 3, "grades" : [ 85, 100, 90 ] } ] )
grades 配列内の値が 80 である最初の要素を 82 に更新する場合、配列内の要素の位置が不明なときは、次のように位置演算子 $ を使用します。
重要
配列フィールドをqueryドキュメントの一部として含める必要があります。
db.students.updateOne( { _id: 1, grades: 80 }, { $set: { "grades.$" : 82 } } )
位置演算子 は、アップデート$ クエリ ドキュメント の 最初の一致 のプレースホルダーとして機能し 。
操作後、students コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "grades" : [ 85, 82, 80 ] } { "_id" : 2, "grades" : [ 88, 90, 92 ] } { "_id" : 3, "grades" : [ 85, 100, 90 ] }
配列内のドキュメントを更新
位置演算子 $ は、埋め込みドキュメントを含む配列の更新を容易にします。位置演算子 $ を使用して $ 演算子上のドット表記の埋め込みドキュメント内のフィールドにアクセスします。
db.collection.updateOne( { <query selector> }, { <update operator>: { "array.$.field" : value } } )
students コレクション内の grades 要素の値が埋め込みドキュメントの配列である次のドキュメントを考えます。
{ _id: 4, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 85, mean: 85, std: 8 } ] }
位置指定の$演算子を使用して、 gradeが85に等しい条件に一致する最初の配列要素のstdフィールドを更新します。
重要
配列フィールドをqueryドキュメントの一部として含める必要があります。
db.students.updateOne( { _id: 4, "grades.grade": 85 }, { $set: { "grades.$.std" : 6 } } )
操作後、ドキュメントには次の更新された値が含まれます。
{ "_id" : 4, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 8 }, { "grade" : 85, "mean" : 90, "std" : 6 }, { "grade" : 85, "mean" : 85, "std" : 8 } ] }
複数のフィールド一致を使用した埋め込みドキュメントの更新
$ 演算子は、$elemMatch 演算子で指定された複数のクエリ条件に一致する最初の配列要素を更新できます。
students コレクション内の grades フィールド値が埋め込みドキュメントの配列である次のドキュメントを考えます。
{ _id: 5, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 90, mean: 85, std: 3 } ] }
以下の例では、$ 演算子は、grade フィールドの値が 90 以下で、mean フィールドの値が 80 より大きい最初の埋め込みドキュメントの std フィールドの値を更新します。
db.students.updateOne( { _id: 5, grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } } }, { $set: { "grades.$.std" : 6 } } )
この操作は、条件に一致する最初の埋め込みドキュメント、つまり配列内の 2 番目の埋め込みドキュメントを更新します。
{ _id: 5, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 6 }, { grade: 90, mean: 85, std: 3 } ] }
複数の配列の一致による更新
クエリにコレクション内のドキュメントをフィルタリングするための複数のフィールドがある場合、更新用の位置演算子 $ の動作はあいまいになります。
学生情報の配列を保持するstudents_deans_listコレクション内のドキュメントを検討します。
db.students_deans_list.insertMany( [ { _id: 8, activity_ids: [ 1, 2 ], grades: [ 90, 95 ], deans_list: [ 2021, 2020 ] } ] )
次の例では、ユーザーは deans_list フィールドの変更を試み、 activity_ids、 deans_list、および grades フィールドを使用してドキュメントをフィルタリングし、 deans_list フィールドの 2021 の値を 2022 に更新します。
db.students_deans_list.updateOne( { activity_ids: 1, grades: 95, deans_list: 2021 }, { $set: { "deans_list.$": 2022 } } )
サーバーが上記の updateOne メソッドを実行するときに、指定された配列フィールド内の値を使用して使用可能なドキュメントをフィルタリングします。deans_list フィールドはフィルターで使用されますが、配列内の更新位置を決定するために更新用の位置演算子 $ によって使用されるフィールドではありません。
db.students_deans_list.find( { _id: 8 } )
出力例:
{ _id: 8, activity_ids: [ 1, 2 ], grades: [ 90, 95 ], deans_list: [ 2021, 2022 ] }
updateOne メソッドは 2021 上の deans_list フィールドと一致しましたが、更新用の位置演算子 $ は代わりに 2020 の値を 2022 に変更しました。
複数の配列を照合するときに予期しない結果にならないように、代わりにフィルターされた位置演算子$[<identifier>]を使用します。
詳細
配列を更新するために $ 演算子を使用する例については、「MQL位置演算子を使用したドキュメント内の配列要素の更新」を参照してください。