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

db.collection.updateMany()

項目一覧

  • 定義
  • 互換性
  • 構文
  • アクセス制御
  • 動作

MongoDB とドライバー

このページでは、 mongosh メソッドについて説明します。MongoDB ドライバーで同等のメソッドを確認するには、ご使用のプログラミング言語の対応するページを参照してください。

C#Java SyncNode.jsPyMongoCC++GoJava RSKotlin CoroutineKotlin SyncPHPMongoidRustScala
db.collection.updateMany(filter, update, options)

コレクションに対して指定したフィルターに一致するすべてのドキュメントを更新します。

このメソッドは、次の環境でホストされている配置で使用できます。

  • MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです

注意

このコマンドは、すべての MongoDB Atlas クラスターでサポートされています。すべてのコマンドに対する Atlas のサポートについては、「サポートされていないコマンド」を参照してください。

  • MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン

  • MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン

updateMany() メソッドの形式は次のとおりです。

db.collection.updateMany(
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string>,
let: <document>
}
)

updateMany() メソッドは次のパラメーターを取ります。

Parameter
タイプ
説明

ドキュメント

更新の選択基準。find()メソッドと同じクエリ セレクターを使用できます。

コレクション内のすべてのドキュメントを更新するには、空のドキュメント { } を指定します。

ドキュメントまたはパイプライン

適用される変更内容。次のいずれかになります。

次の集計ステージのみが含まれます。

詳細については、「 集計パイプラインによる更新 」を参照してください。

置き換えドキュメントを使用して更新するには、db.collection.replaceOne()を参照してください。

upsert

ブール値

任意。 trueの場合、updateMany() は次のいずれかになります。

  • filter に一致するドキュメントがない場合は、新しいドキュメントを作成します。詳しくは、「アップサートの動作」を参照してください。

  • filter に一致するドキュメントを更新します。

複数のアップサートを回避するため、filter フィールドにユニークインデックスが付けられていることを確認します。

デフォルトは false です。

writeConcern

ドキュメント

任意。書込み保証(write concern)を表現するドキュメント。デフォルトの書込み保証を使用する場合は省略します。

トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。

collation

ドキュメント

任意。

操作に使用する照合を指定します。

照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。

照合オプションの構文は次のとおりです。

collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

照合を指定する場合、locale フィールドは必須ですが、その他の照合フィールドはすべて任意です。フィールドの説明については、照合ドキュメントを参照してください。

照合が指定されていなくても、コレクションにデフォルトの照合が設定されている場合(db.createCollection() を参照)には、コレクションの照合が使用されます。

コレクションにも操作にも照合が指定されていない場合、MongoDB では以前のバージョンで使用されていた単純なバイナリ比較によって文字列が比較されます。

1 つの操作に複数の照合は指定できません。たとえば、フィールドごとに異なる照合を指定できません。また、ソートと検索を一度に実行する場合、検索とソートで別の照合を使用できません。

arrayFilters

配列

任意。配列フィールドの更新操作でどの配列要素を変更するかを決定するフィルター ドキュメントの配列。

アップデート ドキュメントでは、$[<identifier>] フィルター処理された位置演算子を使用して識別子を定義し、配列フィルター ドキュメントで参照します。識別子がアップデートドキュメントに含まれていない場合、識別子の配列フィルタードキュメントを作成することはできません。

<identifier>は小文字で始まり、含めることができるのは英数字のみです。

アップデート ドキュメントには同じ識別子を複数回含めることができます。ただし、アップデート ドキュメント内の個別の識別子 ($[identifier]) それぞれに対し、対応する配列フィルター ドキュメントを 1 つだけ指定する必要があります。つまり、同じ識別子に対して複数の配列フィルター ドキュメントを指定することはできません。たとえば、アップデート ステートメントに識別子 x が(場合によっては複数回)含まれている場合、x に 2 つの個別のフィルタ ドキュメントを含む arrayFilters に対して、次のように指定することはできません。

// INVALID
[
{ "x.a": { $gt: 85 } },
{ "x.b": { $gt: 80 } }
]

ただし、次の例のように、単一のフィルター ドキュメント内の同じ識別子に複合条件を指定できます。

// Example 1
[
{ $or: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 2
[
{ $and: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 3
[
{ "x.a": { $gt: 85 }, "x.b": { $gt: 80 } }
]

例については、「 配列更新操作に を指定する 」を参照してください。arrayFilters

ドキュメントまたは文字列

任意。クエリ述語をサポートするために使用するインデックスを指定するドキュメントまたは string です。

このオプションには、インデックス仕様ドキュメントまたはインデックス名の文字列を指定できます。

存在しないインデックスを指定した場合、操作はエラーになります。

例については、「 hint更新操作での の指定 」を参照してください。

let

ドキュメント

任意。

変数のリストを含むドキュメントを指定します。これにより、変数をクエリテキストから分離することで、コマンドの読みやすさを向上させることができます。

ドキュメントの構文は次のとおりです。

{
<variable_name_1>: <expression_1>,
...,
<variable_name_n>: <expression_n>
}

変数は式によって返された値に設定され、その後は変更できません。

コマンド内の変数の値にアクセスするには、二重ドル記号の接頭辞($$)を $$<variable_name> 形式にした変数名とともに使用します。たとえば次のとおりです。$$targetTotal

結果のフィルタリングに変数を使用するには、$expr 演算子内の変数にアクセスする必要があります。

letと変数を使用した例については、let 変数を使用した更新を参照してください。

このメソッドは、次の内容を含むドキュメントを返します。

  • 操作が書き込み保証付きで実行された場合はブール値acknowledgedtrue )、書き込み保証が無効になっている場合はfalseになります

  • matchedCount 一致したドキュメントの数を含みます

  • modifiedCount 変更されたドキュメントの数を含みます

  • upsertedId 、アップサートされたドキュメントの _id が含まれる

  • upsertedCount アップサートされた文書の数を含む

authorizationを使用して実行されている配置では、ユーザーには次の特権を含むアクセス権が必要です。

  • update 指定したコレクションに対するアクション。

  • find 指定したコレクションに対するアクション。

  • insert 操作の結果がアップサートになる場合、指定されたコレクションに対して実行されるアクション。

組み込みロール readWrite は必要な特権を提供します。

updateMany() は、コレクション内で filter と一致するすべてのドキュメントを検索し、update パラメータで指定された変更を適用します。

updateMany() updateMany()は、各ドキュメントを個別に変更します。各ドキュメントの書込みはアトミック操作ですが、 全体はアトミックではありません。ユースケースで複数のドキュメントへの書込みのアトミック性が必要な場合は、 トランザクション を使用します。

1 つのドキュメントの更新が失敗した場合、失敗する前に書き込まれたすべてのドキュメントの更新は保持されますが、残りの一致するドキュメントは更新されません。この動作の詳細については、「 Multi更新の失敗 」を参照してください。

Tip

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

シャーディングされたコレクションでの updateMany()動作の詳細については、「 シャーディングされたコレクション 」を参照してください。

  • updateMany() は、冪等操作にのみ使用してください。

upsert: true で、filter に一致するドキュメントがない場合、db.collection.updateMany() では filterupdate パラメーターに基づき新しいドキュメントが作成されます。

シャーディングされたコレクションで upsert: true を指定する場合、filter には完全なシャードキーを含める必要があります。追加の db.collection.updateMany() 動作については、「シャーディングされたコレクション」を参照してください。

アップサートによる複数のドキュメントの更新」を参照してください。

変更仕様の場合、db.collection.updateMany() メソッドでは更新演算子式のみを含むドキュメントを受け入れ可能です。

以下に例を挙げます。

db.collection.updateMany(
<query>,
{ $set: { status: "D" }, $inc: { quantity: 2 } },
...
)

db.collection.updateMany() メソッドでは、集計パイプライン [ <stage1>, <stage2>, ... ] を受け入れて、実行する変更を指定できます。このパイプラインには次のステージが含まれる可能性があります。

集計パイプラインを使用すると、現在のフィールド値に基づいて条件付きのアップデートを表現したり、あるフィールドを他のフィールドの値を使用してアップデートするなど、より表現内容の多いアップデート ステートメントが可能になります。

以下に例を挙げます。

db.collection.updateMany(
<query>,
[
{ $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } },
{ $unset: [ "misc1", "misc2" ] }
]
...
)

注意

このパイプラインでは、$set$unset は集計ステージで、更新演算子とは対照的です。集計ステージ$set$unsetでは、ドキュメントに新しいフィールドが追加され、既存のフィールド値は変更されません。

更新演算子の詳細については、 $set$unsetを参照してください。

例については、「集計パイプラインによる更新」を参照してください。

更新操作によりドキュメントのサイズが変更された場合、操作は失敗します。

updateMany() メソッドは、MongoDB 5.1 以降の時系列コレクションで使用できます。

更新コマンドは、次の要件を満たしている必要があります。

  • 照合できるのは、 metaField フィールドの値のみです。

  • 変更できるのは、 metaField フィールドの値のみです。

  • 更新ドキュメントには、更新演算子式しか含めることができません。

  • 更新コマンドでは、更新されるドキュメント数を制限せず、multi: true を設定するか、updateMany() メソッドを使用します。

  • 更新コマンドでは upsert: true を設定しないでください。

updateMany() は、シャーディングされたコレクションで使用すると、次の動作を示します。

  • updateMany() upsert: true を含む操作には、filter に完全なシャードキーを含める必要があります。

  • updateMany()範囲移行 またはシャードキー値の更新 中に を実行しようとすると、一部のシナリオでは操作によってドキュメントが失われる可能性があります。すべてのドキュメントが更新されるようにするには、 冪等更新 を使用し、それ以上の更新が適用されなくなるまでコマンドを再実行します。 を使用した冪等更新の詳細については、「updateMany() 冪等更新 」を参照してください。

updateMany()db.collection.explain() は互換性がありません。

db.collection.updateMany()分散トランザクション内で使用できます。

重要

ほとんどの場合、分散トランザクションでは 1 つのドキュメントの書き込み (write) よりもパフォーマンス コストが高くなります。分散トランザクションの可用性は、効果的なスキーマ設計の代わりにはなりません。多くのシナリオにおいて、非正規化されたデータモデル(埋め込みドキュメントと配列)が引き続きデータやユースケースに最適です。つまり、多くのシナリオにおいて、データを適切にモデリングすることで、分散トランザクションの必要性を最小限に抑えることができます。

トランザクションの使用に関するその他の考慮事項(ランタイム制限や oplog サイズ制限など)については、「本番環境での考慮事項」も参照してください。

トランザクションがクロスシャード間書込みトランザクション(write transaction)でない場合に、分散トランザクション内にコレクションとインデックスを作成できます。

db.collection.updateMany()upsert: trueは、既存のコレクションまたは存在しないコレクションで実行できます。存在しないコレクションに対して実行すると、操作によってコレクションが作成されます。

トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。

updateMany() は、正常にアップデートされた各ドキュメントのoplog (操作ログ)にエントリを追加します。ドキュメントが更新されていない場合、updateMany() はoplogにエントリを追加しません。

次の例では、updateMany() を使用した冪等更新を示しています。

会社は、$100、000 未満のすべての従業員に $1、000 のアップグレードを提供しています。

以下のドキュメントを持つemployeesコレクションを検討してください。

db.employees.insertMany( [
{ "_id" : 1, "name" : "Rob", "salary" : 37000 },
{ "_id" : 2, "name" : "Trish", "salary" : 65000 },
{ "_id" : 3, "name" : "Zeke", "salary" : 99999 },
{ "_id" : 4, "name" : "Mary", "salary" : 200000 }
] )

次のコマンドは、$100、000 未満であり、昇順がないすべての従業員に一致し、それらの給与を $1、000 ずつ増加させ、raiseApplied を true に設定します。

db.employees.updateMany(
{ salary: { $lt: 100000 }, raiseApplied: { $ne: true } },
{ $inc: { salary: 1000 }, $set: { raiseApplied: true } }
)

updateMany() は一致する employee ドキュメントを個別に変更します。個々のドキュメントのアップデートはアトミック操作ですが、updateMany()操作全体はアトミックではありません。

操作が失敗して一致するすべてのドキュメントのアップデートに失敗した場合は、指定されたフィルターに一致するドキュメントがなくなるまで、冪等コマンドを安全に再実行できます。この場合、コマンドが冪等であるため、再試行回数に関係なく、各ドキュメントの salaryフィールドは 1 回だけ更新されます。

資格のある従業員がすべてアップグレードされたら、次のコマンドで raiseAppliedフィールドを削除できます。

db.employees.updateMany(
{ },
{ $unset: { raiseApplied: 1 } }
)

restaurant コレクションには次のドキュメントが含まれます。

{ "_id" : 1, "name" : "Central Perk Cafe", "violations" : 3 }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Sub", "violations" : 5 }
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "violations" : 8 }

次の操作は、 violations4 より大きいすべてのドキュメントを更新し、$set フラグを "レビュー" に設定します。

try {
db.restaurant.updateMany(
{ violations: { $gt: 4 } },
{ $set: { "Review" : true } }
);
} catch (e) {
print(e);
}

この操作では以下が返されます。

{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

コレクションには、次のドキュメントが含まれています。

{ "_id" : 1, "name" : "Central Perk Cafe", "violations" : 3 }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Sub", "violations" : 5, "Review" : true }
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "violations" : 8, "Review" : true }

一致するものが見つからなかった場合、以下の結果が返されます。

{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 }

upsert: true を設定すると、一致するものが見つからない場合にはドキュメントが挿入されます。

db.collection.updateMany()は、更新に集計パイプラインを使用できます。パイプラインは、次のステージで設定できます。

集計パイプラインを使用すると、現在のフィールド値に基づいて条件付きのアップデートを表現したり、あるフィールドを他のフィールドの値を使用してアップデートするなど、より表現内容の多いアップデート ステートメントが可能になります。

次の例では、集計パイプラインを使用して、ドキュメント内の他のフィールドの値を使用してフィールドを変更します。

次のドキュメントを使用して students コレクションを作成します。

db.students.insertMany( [
{ "_id" : 1, "student" : "Skye", "points" : 75, "commentsSemester1" : "great at math", "commentsSemester2" : "loses temper", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") },
{ "_id" : 2, "students" : "Elizabeth", "points" : 60, "commentsSemester1" : "well behaved", "commentsSemester2" : "needs improvement", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }
] )

commentsSemester1 フィールドと commentsSemester2 フィールドを別々にするのではなく、これらを新しい comments フィールドにまとめるとします。次に示す更新操作では、集計パイプラインを使用して次のようにします。

  • 新しいcommentsフィールドを追加し、 lastUpdateフィールドを設定します。

  • コレクション内にあるすべてのドキュメントのcommentsSemester1フィールドとcommentsSemester2フィールドを削除します。

db.students.updateMany(
{ },
[
{ $set: { comments: [ "$commentsSemester1", "$commentsSemester2" ], lastUpdate: "$$NOW" } },
{ $unset: [ "commentsSemester1", "commentsSemester2" ] }
]
)

注意

このパイプラインでは、$set$unset は集計ステージで、更新演算子とは対照的です。集計ステージ$set$unsetでは、ドキュメントに新しいフィールドが追加され、既存のフィールド値は変更されません。

更新演算子の詳細については、 $set$unsetを参照してください。

第 1 ステージ

$set段階:

  • 新しい配列フィールドcommentsを作成します。その要素としてcommentsSemester1フィールドとcommentsSemester2フィールドの現在の内容を含めます。

  • フィールドlastUpdateを集計変数NOWの値に設定します。集計変数 NOW は現在の日時値に変換され、パイプライン全体で維持されます。集計変数にアクセスするには、変数の前に二重ドル記号$$を付け、引用符で囲みます。

第 2 ステージ
$unsetステージでは、 commentsSemester1フィールドとcommentsSemester2フィールドが削除されます。

コマンドの実行後、コレクションには次のドキュメントが含まれます。

{ "_id" : 1, "student" : "Skye", "status" : "Modified", "points" : 75, "lastUpdate" : ISODate("2020-01-23T05:11:45.784Z"), "comments" : [ "great at math", "loses temper" ] }
{ "_id" : 2, "student" : "Elizabeth", "status" : "Modified", "points" : 60, "lastUpdate" : ISODate("2020-01-23T05:11:45.784Z"), "comments" : [ "well behaved", "needs improvement" ] }

集計パイプラインを使用すると、現在のフィールド値に基づく条件付きアップデートを実行したり、アップデート時に別個のフィールド値の計算に現在のフィールド値を使用することができます。

たとえば、以下のドキュメントでstudents3コレクションを作成する場合、

db.students3.insertMany( [
{ "_id" : 1, "tests" : [ 95, 92, 90 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") },
{ "_id" : 2, "tests" : [ 94, 88, 90 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") },
{ "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }
] )

集計パイプラインを使用すると、計算されたグレード平均およびレターグレードでドキュメントを更新することができます。

db.students3.updateMany(
{ },
[
{ $set: { average : { $trunc: [ { $avg: "$tests" }, 0 ] } , lastUpdate: "$$NOW" } },
{ $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"
} } } }
]
)

注意

このパイプラインでは、$set$unset は集計ステージで、更新演算子とは対照的です。集計ステージ$set$unsetでは、ドキュメントに新しいフィールドが追加され、既存のフィールド値は変更されません。

更新演算子の詳細については、 $set$unsetを参照してください。

第 1 ステージ

$set段階:

  • testsフィールドの平均に基づいて新しいフィールドaverageを計算します。$avg集計演算子の詳細については$avgを参照してください。 $trunc切り捨て集計演算子の詳細については$truncを参照してください。

  • フィールドlastUpdateを集計変数NOWの値に設定します。集計変数 NOW は現在の日時値に変換され、パイプライン全体で維持されます。集計変数にアクセスするには、変数の前に二重ドル記号$$を付け、引用符で囲みます。

第 2 ステージ
$setステージでは、前のステージで計算されたaverageフィールドに基づいて新しいフィールドgradeが計算されます。集計演算子 $switch の詳細については、$switch を参照してください。

コマンドの実行後、コレクションには次のドキュメントが含まれます。

{ "_id" : 1, "tests" : [ 95, 92, 90 ], "lastUpdate" : ISODate("2020-01-24T17:31:01.670Z"), "average" : 92, "grade" : "A" }
{ "_id" : 2, "tests" : [ 94, 88, 90 ], "lastUpdate" : ISODate("2020-01-24T17:31:01.670Z"), "average" : 90, "grade" : "A" }
{ "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2020-01-24T17:31:01.670Z"), "average" : 75, "grade" : "C" }

Tip

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

inspectors コレクションには次のドキュメントが含まれます。

{ "_id" : 92412, "inspector" : "F. Drebin", "Sector" : 1, "Patrolling" : true },
{ "_id" : 92413, "inspector" : "J. Clouseau", "Sector" : 2, "Patrolling" : false },
{ "_id" : 92414, "inspector" : "J. Clouseau", "Sector" : 3, "Patrolling" : true },
{ "_id" : 92415, "inspector" : "R. Coltrane", "Sector" : 3, "Patrolling" : false }

次の操作では、 Sector が 4 より大きく、 inspector"R. Coltrane" に等しいすべてのドキュメントを更新します。

try {
db.inspectors.updateMany(
{ "Sector" : { $gt : 4 }, "inspector" : "R. Coltrane" },
{ $set: { "Patrolling" : false } },
{ upsert: true }
);
} catch (e) {
print(e);
}

この操作では以下が返されます。

{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("56fc5dcb39ee682bdc609b02"),
"upsertedCount": 1
}

コレクションには、次のドキュメントが含まれています。

{ "_id" : 92412, "inspector" : "F. Drebin", "Sector" : 1, "Patrolling" : true },
{ "_id" : 92413, "inspector" : "J. Clouseau", "Sector" : 2, "Patrolling" : false },
{ "_id" : 92414, "inspector" : "J. Clouseau", "Sector" : 3, "Patrolling" : true },
{ "_id" : 92415, "inspector" : "R. Coltrane", "Sector" : 3, "Patrolling" : false },
{ "_id" : ObjectId("56fc5dcb39ee682bdc609b02"), "inspector" : "R. Coltrane", "Patrolling" : false }

フィルターに一致するドキュメントがなく、upserttrue であったため、updateMany() では生成された _idfilter と同じ条件、および update 修飾子を持つドキュメントが挿入されました。

3つのノードから成るレプリカセットにおいて、次の操作は wmajoritywtimeout100 を指定します。

try {
db.restaurant.updateMany(
{ "name" : "Pizza Rat's Pizzaria" },
{ $inc: { "violations" : 3}, $set: { "Closed" : true } },
{ w: "majority", wtimeout: 100 }
);
} catch (e) {
print(e);
}

承認に wtimeout 制限時間を超える時間がかかると、次の例外が発生します。

WriteConcernError({
"code" : 64,
"errmsg" : "waiting for replication timed out",
"errInfo" : {
"wtimeout" : true,
"writeConcern" : {
"w" : "majority",
"wtimeout" : 100,
"provenance" : "getLastErrorDefaults"
}
}
})

次の表は、errInfo.writeConcern.provenanceの値について説明したものです。

出所
説明

clientSupplied

書き込み保証(write concern)がアプリケーションで指定されました。

customDefault

書込み保証 (write concern) は、カスタム定義されたデフォルト値に基づきます。setDefaultRWConcern を参照してください。

getLastErrorDefaults

書込み保証 (write concern) は、レプリカセットの settings.getLastErrorDefaults のフィールドに基づきます。

implicitDefault

他の書き込み保証(write concern)が一切指定されていない状態で、サーバーから発生した書き込み保証。

照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。

コレクション myCollは、次のドキュメントを含みます。

{ _id: 1, category: "café", status: "A" }
{ _id: 2, category: "cafe", status: "a" }
{ _id: 3, category: "cafE", status: "a" }

次の操作には照合オプションが含まれます。

db.myColl.updateMany(
{ category: "cafe" },
{ $set: { status: "Updated" } },
{ collation: { locale: "fr", strength: 1 } }
);

配列フィールドを更新するときに、どの配列要素を更新するかを決定するための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(
{ grades: { $gte: 100 } },
{ $set: { "grades.$[element]" : 100 } },
{ arrayFilters: [ { "element": { $gte: 100 } } ] }
)

操作後、コレクションには次のドキュメントが含まれます。

{ "_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.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 }
]
}

次のドキュメントを使用してサンプルstudents コレクションを作成します。

db.students.insertMany( [
{ "_id" : 1, "student" : "Richard", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null },
{ "_id" : 2, "student" : "Jane", "grade" : "A", "points" : 60, "comments1" : "well behaved", "comments2" : "fantastic student" },
{ "_id" : 3, "student" : "Ronan", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null },
{ "_id" : 4, "student" : "Noah", "grade" : "D", "points" : 20, "comments1" : "needs improvement", "comments2" : null },
{ "_id" : 5, "student" : "Adam", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null },
{ "_id" : 6, "student" : "Henry", "grade" : "A", "points" : 86, "comments1" : "fantastic student", "comments2" : "well behaved" }
] )

コレクションに次のインデックスを作成します。

db.students.createIndex( { grade: 1 } )

次の更新操作は、インデックス{ grade: 1 }を使用することを明示的に示しています。

注意

存在しないインデックスを指定した場合、操作はエラーになります。

db.students.updateMany(
{ "points": { $lte: 20 }, "grade": "F" },
{ $set: { "comments1": "failed class" } },
{ hint: { grade: 1 } }
)

update コマンドは次を返します。

{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }

ヒントで指定したインデックスが使用されているかどうかを確認するには、$indexStats パイプラインを実行します。

db.students.aggregate( [ { $indexStats: { } }, { $sort: { name: 1 } }, { $match: {key: { grade: 1 } } } ] )

MongoDB 7.0 以降では、新しい USER_ROLES システム変数を使用してユーザー ロールを返すことができます。

このセクションの例では、医療情報を含むコレクション内のフィールドの更新を示します。この例では、USER_ROLES システム変数から現在のユーザー ロールを読み取り、ユーザーが特定のロールを持っている場合にのみ更新を実行します。

システム変数を使用するには、変数名の先頭に $$ を追加します。システム変数 USER_ROLES$$USER_ROLES として指定します。

この例では、次のユーザーを作成します。

  • James Billing ロールの使用

  • Michelle Provider ロールの使用

ロール、ユーザー、コレクションを作成するには、次の手順を実行します。

1

必要な権限とリソースを持つ Billing および Provider という名前のロールを作成します。

実行:

db.createRole( { role: "Billing", privileges: [ { resource: { db: "test",
collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } )
db.createRole( { role: "Provider", privileges: [ { resource: { db: "test",
collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } )
2

必要なロールを持つ James および Michelle という名前のユーザーを作成します。

db.createUser( {
user: "James",
pwd: "js008",
roles: [
{ role: "Billing", db: "test" }
]
} )
db.createUser( {
user: "Michelle",
pwd: "me009",
roles: [
{ role: "Provider", db: "test" }
]
} )
3

実行:

db.medical.insertMany( [
{
_id: 0,
patientName: "Jack Jones",
diagnosisCode: "CAS 17",
creditCard: "1234-5678-9012-3456"
},
{
_id: 1,
patientName: "Mary Smith",
diagnosisCode: "ACH 01",
creditCard: "6541-7534-9637-3456"
}
] )

Provider ロールを持つ Michelle としてログインし、更新を実行します。

1

実行:

db.auth( "Michelle", "me009" )
2

実行:

// Attempt to update many documents
db.medical.updateMany(
// User must have the Provider role to perform the update
{ $expr: { $ne: [ {
$setIntersection: [ [ "Provider" ], "$$USER_ROLES.role" ] }, []
] } },
// Update diagnosisCode
{ $set: { diagnosisCode: "ACH 02"} }
)

前の例では、$setIntersection を使用して、"Provider" s文字列と $$USER_ROLES.role のユーザー ロールの共通部分が空ではないドキュメントを返します。MichelleProvider のロールを持つので、更新が実行されます。

次に、Provider ロールを持たない James としてログインし、同じ更新の実行を試みます。

1

実行:

db.auth( "James", "js008" )
2

実行:

// Attempt to update many documents
db.medical.updateMany(
// User must have the Provider role to perform the update
{ $expr: { $ne: [ {
$setIntersection: [ [ "Provider" ], "$$USER_ROLES.role" ] }, []
] } },
// Update diagnosisCode
{ $set: { diagnosisCode: "ACH 02"} }
)

前の例では、ドキュメントは更新されません。

戻る

db.collection.update