定義
updateupdateコマンドはコレクション内のドキュメントを変更します。1 つのupdateコマンドに複数のアップデート ステートメントを含めることができます。Tip
mongoshでは、このコマンドは 、updateOne()、updateMany()、replaceOne()、findOneAndReplace()、およびヘルパー メソッドfindOneAndUpdate()を通じて実行することもできます。ヘルパー メソッドは
mongoshユーザーには便利ですが、データベースコマンドと同じレベルの情報は返されない可能性があります。 便宜上必要ない場合、または追加の戻りフィールドが必要な場合は、 データベースコマンドを使用します。
互換性
このコマンドは、次の環境でホストされている配置で使用できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
注意
このコマンドは、すべての MongoDB Atlas クラスターでサポートされています。すべてのコマンドに対する Atlas のサポートについては、「サポートされていないコマンド」を参照してください。
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
構文
バージョン 5.0 での変更。
このコマンドの構文は、次のとおりです。
db.runCommand( { update: <collection>, updates: [ { q: <query>, u: <document or pipeline>, c: <document>, // Added in MongoDB 5.0 upsert: <boolean>, multi: <boolean>, collation: <document>, arrayFilters: <array>, hint: <document|string> }, ... ], ordered: <boolean>, maxTimeMS: <integer>, writeConcern: { <write concern> }, bypassDocumentValidation: <boolean>, comment: <any>, let: <document> // Added in MongoDB 5.0 } )
コマンドフィールド
このコマンドは、次のフィールドを使用します。
フィールド | タイプ | 説明 | |||||
|---|---|---|---|---|---|---|---|
| string | ターゲット コレクションの名前。 | |||||
| 配列 | 名前付きコレクションに対して実行する 1 つ以上のアップデート ステートメントの配列。 更新 ステートメントの詳細については、「 更新 ステートメント 」を参照してください。 | |||||
| ブール値 | オプション。 | |||||
| non-negative integer | 任意。 時間制限をミリ秒単位で指定します。 MongoDB は、 | |||||
| ドキュメント | 任意。 コマンドの トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。 | |||||
| ブール値 | 任意。 | |||||
| any | 任意。このコマンドに添付するユーザー指定のコメント。設定すると、このコメントは以下の場所にこのコマンドの記録と合わせて表示されます。
コメントには、有効な BSON 型(string, integer, object, array など)を使用できます。 | |||||
ドキュメント | 任意。 変数のリストを含むドキュメントを指定します。これにより、変数をクエリテキストから分離することで、コマンドの読みやすさを向上させることができます。 ドキュメントの構文は次のとおりです。 変数は式によって返された値に設定され、その後は変更できません。 コマンド内の変数の値にアクセスするには、二重ドル記号の接頭辞( 完全な例については、「 オプションまたは フィールドで変数を使用する バージョン 5.0 で追加 |
アップデート ステートメント
updates配列の各要素は、アップデート ステートメント ドキュメントです。各ドキュメントには、次のフィールドが含まれています。
フィールド | タイプ | 説明 | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ドキュメント | ||||||||||||||||||||
ドキュメントまたはパイプライン | 適用される修正。値は次のいずれかになります。
詳細については、「 動作 」を参照してください。 | |||||||||||||||||||
ドキュメント | 任意。 変数のリストを含むドキュメントを指定します。これにより、変数をクエリテキストから分離することで、コマンドの読みやすさを向上させることができます。 ドキュメントの構文は次のとおりです。 変数は式によって返された値に設定され、その後は変更できません。 コマンド内の変数の値にアクセスするには、二重ドル記号の接頭辞( 結果のフィルタリングに変数を使用するには、
バージョン 5.0 で追加 | |||||||||||||||||||
ブール値 | 任意。
複数の デフォルトは | |||||||||||||||||||
| ブール値 | オプション。 複数のドキュメントを更新する場合、1 つのドキュメントが更新に失敗すると、それ以降のドキュメントは更新されません。 この動作の詳細については、「 Multi更新の失敗 」を参照してください。 | ||||||||||||||||||
| ドキュメント | 任意。 操作に使用する照合を指定します。 照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。 照合オプションの構文は次のとおりです。 照合を指定する場合、 照合が指定されていなくても、コレクションにデフォルトの照合が設定されている場合( コレクションにも操作にも照合が指定されていない場合、MongoDB では以前のバージョンで使用されていた単純なバイナリ比較によって文字列が比較されます。 1 つの操作に複数の照合は指定できません。たとえば、フィールドごとに異なる照合を指定できません。また、ソートと検索を一度に実行する場合、検索とソートで別の照合を使用できません。 | ||||||||||||||||||
| 配列 | オプション。配列フィールドのアップデート操作でどの配列要素を変更するかを決定するフィルタードキュメントの配列。 アップデート ドキュメントでは、
アップデート ドキュメントには同じ識別子を複数回含めることができます。ただし、アップデート ドキュメント内の個別の識別子 ( ただし、次の例のように、単一のフィルター ドキュメント内の同じ識別子に複合条件を指定できます。 | ||||||||||||||||||
ドキュメントまたは文字列 | 任意。 クエリ述語をサポートするために使用するインデックスを指定するドキュメントまたは string です。 このオプションには、インデックス仕様ドキュメントまたはインデックス名の文字列を指定できます。 存在しないインデックスを指定した場合、操作はエラーになります。 例については、「 |
戻り値
このコマンドは、操作のステータスを含むドキュメントを返します。例:
{ "ok" : 1, "nModified" : 0, "n" : 1, "upserted" : [ { "index" : 0, "_id" : ObjectId("52ccb2118908ccd753d65882") } ] }
出力フィールドの詳細については、「出力」を参照してください。
アクセス制御
authorizationを使用して実行されている配置では、ユーザーには次の特権を含むアクセス権が必要です。
組み込みロール readWrite は必要な特権を提供します。
動作
制限
multi: true を設定した場合、update コマンドは冪等な操作にのみ使用してください。
更新演算子式ドキュメントを使用したアップデート
アップデートステートメントフィールド u は、 アップデート演算子式のみを含むドキュメントを受け入れることができます。例:
updates: [ { q: <query>, u: { $set: { status: "D" }, $inc: { quantity: 2 } }, ... }, ... ]
次に、 updateコマンドはドキュメント内の対応するフィールドのみを更新します。
置換ドキュメントによる更新
アップデート ステートメント フィールドuフィールドは置換ドキュメントを受け入れることができます。つまり、ドキュメントにはfield:value式のみが含まれます。 例:
updates: [ { q: <query>, u: { status: "D", quantity: 4 }, ... }, ... ]
次に、 updateコマンドは一致するドキュメントをアップデート ドキュメントに置き換えます。 updateコマンドは一致するドキュメントを1 つだけ置き換えることができます。つまり、 multiフィールドはtrueにできません。 updateコマンドは_id値を置き換えません。
Multi アップデートの失敗
multi パラメータがtrue に設定されたアップデートコマンドで 1 つのドキュメントのアップデートに失敗した場合、それ以上のドキュメントはそのコマンドの一部としてはアップデートされません。
たとえば、以下のドキュメントでmembersコレクションを作成する場合、
db.members.insertMany( [ { "_id" : 1, "member" : "Taylor", "status" : "pending", "points" : 1}, { "_id" : 2, "member" : "Alexis", "status" : "enrolled", "points" : 59}, { "_id" : 3, "member" : "Elizabeth", "status" : "enrolled", "points" : 34} ] )
以下の操作では points の値が 60 と等しくなることはできないというルールで members コレクションにドキュメント検証を作成します。
db.runCommand( { collMod: "members", validator: { points: { $ne: 60 } } } )
このアップデート コマンドにより、すべてのドキュメントの points フィールドの値を 1 増やします。
db.runCommand( { update: "members", updates: [ { q: {}, u: { $inc: { points: 1 } }, multi: true } ] } )
コマンドの実行後、コレクションには次のドキュメントが含まれます。
{ _id: 1, member: 'Taylor', status: 'A', points: 2 } { _id: 2, member: 'Alexis', status: 'D', points: 59 } { _id: 3, member: 'Elizabeth', status: 'C', points: 34 }
update コマンドでは 1 番目のドキュメントの points の値がアップデートされましたが、2 番目のドキュメントはアップデートされませんでした。points の値は 60 と等しくならないという検証ルールによるものです。書き込みエラー以降はドキュメントが更新されないため、3 番目のドキュメントは更新されませんでした。
注意
一致したドキュメントのサブセットが更新された場合、たとえば、更新によって一部のドキュメントがスキーマ検証に失敗する場合、update コマンドによって返される nModified の値は正確ではない可能性があります。
集計パイプラインによる更新
アップデート ステートメント フィールド u フィールドでは、集計パイプライン[ <stage1>, <stage2>, ... ]を受け入れて、実行する変更を指定できます。パイプラインは、次のステージで構成できます。
$addFieldsおよびそのエイリアス$set$replaceRootおよびそのエイリアス$replaceWith
集計パイプラインを使用すると、現在のフィールド値に基づいて条件付きのアップデートを表現したり、あるフィールドを他のフィールドの値を使用してアップデートするなど、より表現内容の多いアップデート ステートメントが可能になります。
以下に例を挙げます。
updates: [ { q: <query>, u: [ { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } }, { $unset: [ "misc1", "misc2" ] } ], ... }, ... ]
例については、「集計パイプラインによる更新」を参照してください。
一意なインデックスを使用したアップサート
重複を防ぐためのユニークインデックスがない限り、アップサートによって重複したドキュメントが作成されることがあります。
Andy という名前のドキュメントが存在せず、複数のクライアントがほぼ同時に次のコマンドを発行する例を考えます。
db.runCommand( { update: "people", updates: [ { q: { name: "Andy" }, u: { $inc: { score: 1 } }, multi: true, upsert: true } ] } )
いずれかのクライアントがデータを正常に挿入する前にすべての update 操作がクエリ フェーズを終了し、かつ name フィールドにユニークインデックスがない場合、各 update 操作によって挿入が行われて、name: Andyを含む複数のドキュメントが作成される可能性があります。
name フィールドに一意なインデックスを設定すると、ドキュメントが 1 つだけ作成されるようになります。一意なインデックスが設定されると、複数の update 操作で次の動作が見られるようになります。
正確に 1 つの
update操作で新しいドキュメントが正常に挿入されます。その他の
update操作は、新しく挿入されたドキュメントを更新するか、一意なキーの競合が原因で失敗します。他の
update操作で新しく挿入されたドキュメントを更新するには、次の条件がすべて満たされている必要があります。ターゲット コレクションに一意なインデックスがあるため、重複キー エラーが発生。
更新操作が
updateManyではない、またはmultiがfalse。アップデートの一致条件は、次のいずれかです。
単一の等価述語。例:
{ "fieldA" : "valueA" }等価述語の論理 AND。例:
{ "fieldA" : "valueA", "fieldB" : "valueB" }
等価述語内のフィールドが、一意なインデックス キー パターン内のフィールドと一致。
更新操作が、一意なインデックス キー パターン内のフィールドを変更しない。
次の表に示す upsert 操作の例では、キーの衝突が発生した場合に更新されるか失敗します。
ユニークインデックスキーのパターン | アップデート操作 | 結果 | ||||||
|---|---|---|---|---|---|---|---|---|
| | マッチしたドキュメントの | ||||||
| | 一意なインデックス キー パターン( | ||||||
| | 等式述語フィールド( |
制限
updates 配列内の各アップデート要素について、クエリと更新サイズの合計(qおよびu )は、最大 BSON ドキュメント サイズ以下である必要があります。
updates 配列内の更新ステートメントの総数は、最大バルクサイズ以下である必要があります。
スキーマ検証
update コマンドは、bypassDocumentValidation オプションのサポートを追加します。これにより、検証ルールがあるコレクション内でドキュメントを挿入または更新する際に、スキーマ検証をバイパスできます。
シャーディングされたコレクション
upsert シャーディングされたコレクション
シャーディングされたコレクションでupdateをmulti: falseと併用するには、
upsert: trueを指定しない場合、フィルターqは
_idフィールドに等価一致を含めるか、単一のシャードをターゲットにする(シャードキーを含めるなど)必要があります。upsert: true を指定する場合、フィルターqにはシャードキーの等価一致が含まれている必要があります。
ただし、シャーディングされたコレクション内のドキュメントにはシャードキーのフィールドがない場合があります。シャードキーがないドキュメントを対象とするには、
nullを等価一致の を(_idフィールド上と同じに)別のフィルター条件と組み合わせて使用できます。以下に例を挙げます。{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key
ドキュメントの置換
ドキュメントを置き換えるとき、 updateは最初にクエリフィルターを使用して、1 つのシャードをターゲットにしようとします。 クエリフィルターで単一のシャードをターゲットにできない場合は、置き換えドキュメントをターゲットにしようとします。
シャードキーの変更
シャードキー フィールドが不変の _id フィールドでない限り、ドキュメントのシャードキー値を更新できます。
既存のシャードキー値をupdateで変更するには
必ず
mongos上で使用します。シャードに直接操作を実行しないでください。トランザクション内で、または 再試行可能な書き込みとして実行する必要があります。
必ず
multi: falseを指定します。完全なシャードキーに等価のクエリフィルターを含める必要があります。
Tip
欠落しているキー値は NULL 等価一致の一部として返されるため、NULL 値のキーが更新されないように、必要に応じて追加のクエリ条件(_id フィールドなど)を追加します。
「シャーディングされたコレクションの upsert」も参照してください。
欠落しているシャードキー
シャーディングされたコレクション内のドキュメントには、シャードキー フィールドがない場合があります。updateを使用してドキュメントの欠落しているシャードキーを設定するには、mongosで実行する必要があります。シャードに対して直接操作を実行しないでください。
さらに、次の要件も適用されます。
タスク | 要件 |
|---|---|
設定するには |
|
|
|
Tip
欠落しているキー値は NULL 等価一致の一部として返されるため、NULL 値のキーが更新されないように、必要に応じて追加のクエリ条件(_id フィールドなど)を追加します。
以下も参照してください。
トランザクション
update は分散トランザクション内で使用できます。
重要
ほとんどの場合、分散トランザクションでは 1 つのドキュメントの書き込み (write) よりもパフォーマンス コストが高くなります。分散トランザクションの可用性は、効果的なスキーマ設計の代わりにはなりません。多くのシナリオにおいて、非正規化されたデータモデル(埋め込みドキュメントと配列)が引き続きデータやユースケースに最適です。つまり、多くのシナリオにおいて、データを適切にモデリングすることで、分散トランザクションの必要性を最小限に抑えることができます。
トランザクションの使用に関するその他の考慮事項(ランタイム制限や oplog サイズ制限など)については、「本番環境での考慮事項」も参照してください。
トランザクション内のアップサート
トランザクションがクロスシャード間書き込みトランザクション(write transaction)でない場合に、分散トランザクション内にコレクションとインデックスを作成できます。
update と upsert: trueは、既存のコレクションまたは存在しないコレクションで実行できます。存在しないコレクションに対して実行すると、操作によってコレクションが作成されます。
書込み保証とトランザクション
トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。
例
1 つのドキュメントの特定のフィールドのアップデート
アップデート演算子を使用して、ドキュメントの指定されたフィールドのみを更新します。
たとえば、以下のドキュメントでmembersコレクションを作成する場合、
db.members.insertMany([ { _id: 1, member: "abc123", status: "Pending", points: 0, misc1: "note to self: confirm status", misc2: "Need to activate" }, { _id: 2, member: "xyz123", status: "D", points: 59, misc1: "reminder: ping me at 100pts", misc2: "Some random comment" }, ])
次のコマンドは、 $setおよび$incアップデート演算子を使用して、 memberが"abc123"に等しいドキュメントのstatusフィールドとpointsフィールドを更新します。
db.runCommand( { update: "members", updates: [ { q: { member: "abc123" }, u: { $set: { status: "A" }, $inc: { points: 1 } } } ], ordered: false, writeConcern: { w: "majority", wtimeout: 5000 } } )
<update>ドキュメントではオプションの multi フィールドが指定されていないため、q一致条件に一致するドキュメントが複数ある場合でも、更新によって変更されるのは 1 つのドキュメントのみです。
返されたドキュメントは、コマンドによって複数のドキュメントが見つかり、更新されたことを示しています。このコマンドは、次を返します。
{ "n" : 1, "nModified" : 1, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
詳細については「出力」を参照してください。
コマンドの実行後、コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 1, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" } { "_id" : 2, "member" : "xyz123", "status" : "D", "points" : 59, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
1 つのドキュメントの特定のフィールドのアップデート
アップデート演算子を使用して、ドキュメントの指定されたフィールドのみを更新し、アップデート演算子に true に設定された multi フィールドを含めます。
たとえば、コレクション members に次のドキュメントが含まれているとします。
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 1, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" } { "_id" : 2, "member" : "xyz123", "status" : "D", "points" : 59, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
次のコマンドは、 $setおよび$incアップデート演算子を使用して、コレクション内の全ドキュメントの status フィールドと points フィールドをそれぞれ変更します。
db.runCommand( { update: "members", updates: [ { q: { }, u: { $set: { status: "A" }, $inc: { points: 1 } }, multi: true } ], ordered: false, writeConcern: { w: "majority", wtimeout: 5000 } } )
アップデートにより、q フィールドで指定されたクエリに一致するすべてのドキュメントが変更されます。これはつまり、コレクション内の全ドキュメントに一致する空のクエリです。
返されたドキュメントは、コマンドによって複数のドキュメントが見つかり、更新されたことを示しています。レプリカセットの場合、このコマンドは以下を返します。
{ "n" : 2, "nModified" : 2, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
詳細については「出力」を参照してください。
コマンドの実行後、コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 2, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" } { "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
集約パイプラインによるアップデート
updateコマンドは、更新に集計パイプラインを使用できます。 このパイプラインには次のステージが含まれる可能性があります。
$addFieldsおよびそのエイリアス$set$replaceRootおよびそのエイリアス$replaceWith
集計パイプラインを使用すると、現在のフィールド値に基づいて条件付きのアップデートを表現したり、あるフィールドを他のフィールドの値を使用してアップデートするなど、より表現内容の多いアップデート ステートメントが可能になります。
例 1
次の例では、集計パイプラインを使用して、ドキュメント内の他のフィールドの値を使用してフィールドを変更します。
members コレクションには次の文書が含まれます。
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 2, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" } { "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
misc1 フィールドと misc2 フィールドを分けるのではなく、これらを新しい comments フィールドにまとめるとします。次のアップデート操作では、集計パイプラインを使用して新しい comments フィールドを追加し、コレクション内のすべてのドキュメントの misc1 フィールドと misc2 フィールドを削除します。
まず、
statusフィールドを"Modified"に設定し、他の 2 つのフィールドmisc1およびmisc2の現在の内容が含まれる新しいフィールドcommentsを追加します。次に、
misc1とmisc2のフィールドを除きます。
db.runCommand( { update: "members", updates: [ { q: { }, u: [ { $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } }, { $unset: [ "misc1", "misc2" ] } ], multi: true } ], ordered: false, writeConcern: { w: "majority", wtimeout: 5000 } } )
返されたドキュメントは、コマンドによって複数のドキュメントが見つかり、更新されたことを示しています。このコマンドは、次を返します。
{ "n" : 2, "nModified" : 2, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
詳細については「出力」を参照してください。
コマンドの実行後、コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "member" : "abc123", "status" : "Modified", "points" : 2, "comments" : [ "note to self: confirm status", "Need to activate" ] } { "_id" : 2, "member" : "xyz123", "status" : "Modified", "points" : 60, "comments" : [ "reminder: ping me at 100pts", "Some random comment" ] }
例 2
集計パイプラインを使用すると、現在のフィールド値に基づく条件付きアップデートを実行したり、アップデート時に別個のフィールド値の計算に現在のフィールド値を使用することができます。
db.students.insertMany( [ { "_id" : 1, "tests" : [ 95, 92, 90 ] }, { "_id" : 2, "tests" : [ 94, 88, 90 ] }, { "_id" : 3, "tests" : [ 70, 75, 82 ] } ] );
集計パイプラインを使用すると、計算されたグレード平均およびレターグレードでドキュメントを更新することができます。
db.runCommand( { update: "students", updates: [ { q: { }, u: [ { $set: { average : { $avg: "$tests" } } }, { $set: { grade: { $switch: { branches: [ { case: { $gte: [ "$average", 90 ] }, then: "A" }, { case: { $gte: [ "$average", 80 ] }, then: "B" }, { case: { $gte: [ "$average", 70 ] }, then: "C" }, { case: { $gte: [ "$average", 60 ] }, then: "D" } ], default: "F" } } } } ], multi: true } ], ordered: false, writeConcern: { w: "majority", wtimeout: 5000 } } )
- 第 1 ステージ
$setステージでは、testsフィールドの平均に基づいて新しいフィールドaverageを計算します。集計演算子$avgの詳細については、$avgを参照してください。- 第 2 ステージ
$setステージでは、前のステージで計算されたaverageフィールドに基づいて新しいフィールドgradeが計算されます。集計演算子$switchの詳細については、$switchを参照してください。
返されたドキュメントは、コマンドによって複数のドキュメントが見つかり、更新されたことを示しています。このコマンドは、次を返します。
{ "n" : 3, "nModified" : 3, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
コマンドの実行後、コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "tests" : [ 95, 92, 90 ], "average" : 92.33333333333333, "grade" : "A" } { "_id" : 2, "tests" : [ 94, 88, 90 ], "average" : 90.66666666666667, "grade" : "A" } { "_id" : 3, "tests" : [ 70, 75, 82 ], "average" : 75.66666666666667, "grade" : "C" }
一括アップデート
次の例では、 members コレクションに対して複数のアップデート操作を実行します。
db.runCommand( { update: "members", updates: [ { q: { status: "P" }, u: { $set: { status: "D" } }, multi: true }, { q: { _id: 5 }, u: { _id: 5, name: "abc123", status: "A" }, upsert: true } ], ordered: false, writeConcern: { w: "majority", wtimeout: 5000 } } )
返されたドキュメントは、コマンドが 10 ドキュメントを変更し、_id 値 5 のドキュメントを挿入したことを示しています。詳細については「出力」を参照してください。
{ "ok" : 1, "nModified" : 10, "n" : 11, "upserted" : [ { "index" : 1, "_id" : 5 } ] }
照合の指定
照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。
コレクション myCollは、次のドキュメントを含みます。
{ _id: 1, category: "café", status: "A" } { _id: 2, category: "cafe", status: "a" } { _id: 3, category: "cafE", status: "a" }
次の操作には照合オプションが含まれます。
db.runCommand({ update: "myColl", updates: [ { q: { category: "cafe", status: "a" }, u: { $set: { status: "Updated" } }, collation: { locale: "fr", strength: 1 } } ] })
配列更新操作での arrayFilters の指定
配列フィールドを更新するときに、どの配列要素を更新するかを決定するためのarrayFiltersを指定できます。
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.runCommand( { update: "students", updates: [ { q: { grades: { $gte: 100 } }, u: { $set: { "grades.$[element]" : 100 } }, arrayFilters: [ { "element": { $gte: 100 } } ], multi: true} ] } )
操作後、コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "grades" : [ 95, 92, 90 ] } { "_id" : 2, "grades" : [ 98, 100, 100 ] } { "_id" : 3, "grades" : [ 95, 100, 100 ] }
ドキュメントの配列の特定の要素を更新する
次のドキュメントを使用してコレクション 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.runCommand({ update: "students2", updates: [ { q: { }, u: { $set: { "grades.$[elem].mean" : 100 } }, arrayFilters: [ { "elem.grade": { $gte: 85 } } ], multi: true } ] })
操作後、コレクションには次のドキュメントが含まれます。
{ "_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 } ] }
更新操作に hint を指定する
次のドキュメントを使用してサンプルmembers コレクションを作成します。
db.members.insertMany([ { "_id" : 1, "member" : "abc123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }, { "_id" : 3, "member" : "lmn123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 4, "member" : "pqr123", "status" : "D", "points" : 20, "misc1" : "Deactivated", "misc2" : null }, { "_id" : 5, "member" : "ijk123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 6, "member" : "cde123", "status" : "A", "points" : 86, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" } ])
コレクションに次のインデックスを作成します。
db.members.createIndex( { status: 1 } ) db.members.createIndex( { points: 1 } )
次の更新操作は、インデックス{
status: 1 }を使用することを明示的に示しています。
注意
存在しないインデックスを指定した場合、操作はエラーになります。
db.runCommand({ update: "members", updates: [ { q: { "points": { $lte: 20 }, "status": "P" }, u: { $set: { "misc1": "Need to activate" } }, hint: { status: 1 }, multi: true } ] })
update コマンドは次を返します。
{ "n" : 3, "nModified" : 3, "ok" : 1 }
使用されたインデックスを確認するには、次の操作で explain を実行します。
db.runCommand( { explain: { update: "members", updates: [ { q: { "points": { $lte: 20 }, "status": "P" }, u: { $set: { "misc1": "Need to activate" } }, hint: { status: 1 }, multi: true } ] }, verbosity: "queryPlanner" } )
explainはドキュメントを変更しません。
let オプションまたは c フィールドでの変数の使用
バージョン 5.0 で追加
変数はletオプションまたはcフィールドで定義し、 updates配列でアクセスできます。
注意
変数を使用して結果をフィルタリングするには、$expr 演算子内の変数にアクセスする必要があります。
コレクション cakeFlavors を以下ように作成します。
db.cakeFlavors.insertMany( [ { _id: 1, flavor: "chocolate" }, { _id: 2, flavor: "strawberry" }, { _id: 3, flavor: "cherry" } ] )
次の例では、let で targetFlavor 変数と newFlavor 変数を定義し、その変数を使用してケーキのフレーバーをチェリーからオレンジに変更します。
db.runCommand( { update: db.cakeFlavors.getName(), updates: [ { q: { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } }, u: [ { $set: { flavor: "$$newFlavor" } } ] } ], let : { targetFlavor: "cherry", newFlavor: "orange" } } )
次の例では、c で targetFlavor 変数と newFlavor 変数を定義し、その変数を使用してケーキのフレーバーをチョコレートからバニラに変更します。
db.runCommand( { update: db.cakeFlavors.getName(), updates: [ { q: { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } }, u: [ { $set: { flavor: "$$newFlavor" } } ], c: { targetFlavor: "chocolate", newFlavor: "vanilla" } } ] } )
出力
返されるドキュメントには、次のフィールドのサブセットが含まれます。
update.nupdateコマンドはドキュメントアップデートの配列を受け入れます。その一部はアップサートになる場合があります。アップデートの場合、nはアップデート対象として選択されたドキュメントの数です。アップサートの場合、挿入されたドキュメントのnは1になります。サーバーではすべてのアップデートとアップサートのn値を足し、合計がupdate.nとして返されます。アップデート操作によってドキュメントに変更が生じない場合(例:
$set式は値を現在の値にアップデートし、nはnModifiedより大きくなる可能性があります。
update.nModified更新されたドキュメントの数。 フィールドの値を現在の値に設定するなど、アップデート操作によってドキュメントに変更が生じない場合、
nModifiedはnより小さくなる可能性があります。注意
一致したドキュメントのサブセットが更新された場合、たとえば、更新によって一部のドキュメントがスキーマ検証に失敗する場合、
updateコマンドによって返されるnModifiedの値は正確ではない可能性があります。
update.writeErrors更新操作中に発生したエラーに関する情報を含むドキュメントの配列。
writeErrors配列には、エラーが発生した更新ステートメントごとにエラー ドキュメントが含まれています。各エラー ドキュメントには以下のフィールドが含まれます。
update.writeConcernError更新操作中に発生したエラーに関する情報を含むドキュメントの配列。
バージョン での変更6.0.14 :( でも利用可能5.0.30 ):が で実行されると、1 つ以上の書込みエラーが発生しても、書込み保証 (write
updatemongosconcern)エラーが常に報告されます。以前のリリースでは、書込みエラーが発生すると、 は書込み保証 (writeupdateconcern)エラーを報告しないことがありました。各エラー ドキュメントには以下のフィールドが含まれます。
update.writeConcernError.errInfo.writeConcern対応する操作に使用される書込み保証 (write concern) オブジェクトです。書込み保証 (write concern) オブジェクト フィールドの詳細については、「書込み保証 (write concern) の仕様」を参照してください。
書込み保証 (write concern) オブジェクトには、書込み保証 (write concern) のソースを示す以下のフィールドも含むことができます。
update.writeConcernError.errInfo.writeConcern.provenance書込み保証 (write concern) が発生した場所を示す文字列値です(書込み保証 (write concern)
provenanceと呼ばれます)。次の表は、このフィールドに指定できる値とその意味を示しています。出所説明clientSupplied書き込み保証(write concern)がアプリケーションで指定されました。
customDefault書込み保証 (write concern) は、カスタム定義されたデフォルト値に基づきます。
setDefaultRWConcernを参照してください。getLastErrorDefaults書込み保証 (write concern) は、レプリカセットの
settings.getLastErrorDefaultsのフィールドに基づきます。implicitDefault他の書き込み保証(write concern)が一切指定されていない状態で、サーバーから発生した書き込み保証。
バージョン8.1.2で変更。
update がシャーディングされたクラスター内の mongos で実行されると、他のエラーが 1 つ以上発生した場合でも、レスポンスには常に writeConcernError が報告されます。以前のリリースでは、他のエラーによって update が書込み保証 (write concern)エラーを報告しないことがあります。
例、ドキュメントが検証に失敗して DocumentValidationFailed エラーが発生し、書込み保証 (write concern)エラーも発生した場合、DocumentValidationFailed エラーと writeConcernError の両方が応答の最上位フィールドに返されます。
前述のアップデート固有の戻りフィールドに加えて、 db.runCommand()には追加情報が含まれます。
レプリカ セットの場合、
optime、electionId、$clusterTime、およびoperationTime。シャーディングされたクラスターの場合、
operationTimeおよび$clusterTime。
これらのフィールドの詳細については db.runCommand レスポンスを参照してください。
以下は、アップサートを実行したupdateコマンドが成功した場合に返されるドキュメントの例です。
{ "ok" : 1, "nModified" : 0, "n" : 1, "upserted" : [ { "index" : 0, "_id" : ObjectId("52ccb2118908ccd753d65882") } ] }
以下は、3 つのアップデートステートメントを含む一括アップデートで返されるドキュメントの例です。1 つのアップデートステートメントは成功し、他の 2 つのアップデートステートメントではエラーが発生しました。
{ "ok" : 1, "nModified" : 1, "n" : 1, "writeErrors" : [ { "index" : 1, "code" : 16837, "errmsg" : "The _id field cannot be changed from {_id: 1.0} to {_id: 5.0}." }, { "index" : 2, "code" : 16837, "errmsg" : "The _id field cannot be changed from {_id: 2.0} to {_id: 6.0}." }, ] }