Docs Menu
Docs Home
/
MongoDBマニュアル
/ / / /

$ (update)

項目一覧

  • 定義
  • 互換性
  • 構文
  • 動作
$

位置演算子 $ は、配列内の要素の位置を明示的に指定せずに、更新する配列内の要素を識別します。

注意

曖昧さ回避

  • 読み取り操作から配列要素をプロジェクションするか、または返すには、代わりに「$ プロジェクション演算子」を参照してください。

  • 配列内のすべての要素をアップデートするには、代わりにすべての位置演算子 $[] を参照してください。

  • 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 以降、更新演算子では名前が文字列ベースのドキュメントフィールドを辞書順に処理します。数値名のフィールドは、数値順に処理されます。詳細については、「更新演算子の動作」を参照してください。

挿入では、挿入されたドキュメントのフィールド名として $ が使用されるため、位置演算子 $アップサート 操作で使用しないでください。

位置演算子 $ は、$ プレースホルダーの置換が単一の値であるため、複数の配列を走査するクエリ(他の配列内にネストされた配列を走査するクエリなど)には使用できません

$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 }
]
}

位置指定の$演算子を使用して、 grade85に等しい条件に一致する最初の配列要素の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_idsdeans_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>]を使用します。

Tip

以下も参照してください。

戻る

配列