定義
$位置演算子
$演算子を使用して、配列内の要素の位置を明示的に指定せずに更新する配列内の要素を識別します。注意
曖昧さ回避
読み取り操作から配列要素をプロジェクションするか、または返すには、代わりに「
$プロジェクション演算子」を参照してください。配列内のすべての要素をアップデートするには、代わりにすべての位置演算子
$[]を参照してください。1 つまたは複数の配列フィルター条件に一致するすべての要素を更新するには、
$[<identifier>]の代わりにフィルタリングされた位置演算子を参照してください。
互換性
次の環境でホストされる配置では、位置オペレーター$を使用できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
構文
位置演算子 $ の形式は次のとおりです。
{ "<array>.$" : value }
やdb.collection.updateOne()db.collection.findAndModify() などの更新操作を使用する場合、次の条件の両方が true である必要があります。
$位置演算子 は、 に一致する 最初の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 } ] }
次の例では、 演算子は、$ 以下の値を持つstd フィールドと の値を持つ フィールドを持つ最初の埋め込みドキュメントの フィールドの値を更新します。grade 90mean80より大きい値:
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位置演算子を使用したドキュメント内の配列要素の更新」を参照してください。