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

db.collection.updateOne()

項目一覧

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

MongoDB とドライバー

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

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

フィルターに基づいてコレクション内の単一のドキュメントを更新します。

次の環境でホストされる配置には db.collection.updateOne() を使用できます。

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

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

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

updateOne()メソッドの構文は次のとおりです。

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

db.collection.updateOne() メソッドは次のパラメーターを取ります。

Parameter
タイプ
説明
ドキュメント

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

コレクション内で返される最初のドキュメントを更新するには、空のドキュメント { } を指定します。

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

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

更新演算子式のみが含まれます。

詳細については、「更新演算子式ドキュメントによる更新」を参照してください。

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

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

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

upsert
ブール値

任意。true の場合、updateOne() によって次のいずれかが実行されます。

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

  • filter に一致する 1 つのドキュメントをアップデートします。

複数のアップサートを回避するため、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 変数を使用した更新を参照してください。

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

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

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

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

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

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

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

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

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

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

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

db.collection.updateOne()フィルターに一致する最初のドキュメントを検索し、指定された更新の変更を適用します。

更新仕様の場合、db.collection.updateOne() メソッドは更新演算子式のみを含むドキュメントを受け入れることができます。

以下に例を挙げます。

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

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

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

以下に例を挙げます。

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

注意

パイプライン内で使用される $set$unset は、集計ステージの$set$unset をそれぞれ示しており、アップデートの演算子の$set$unset ではありません。

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

upsert: true で、filter に一致するドキュメントがない場合、db.collection.updateOne() では filter 条件と update の変更に基づいて新しいドキュメントが作成されます。詳細については、「アップサートによる更新」を参照してください。

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

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

シャーディングされたコレクションでdb.collection.updateOne()を使用するには、次の手順に従います。

  • upsert: trueを指定しない場合は、 _idフィールドに完全一致を含めるか、単一のシャードをターゲットにする(フィルターにシャードキーを含めるなど)必要があります。

  • upsert: trueを指定する場合、フィルタにはシャードキーを含める必要があります。

ただし、シャーディングされたコレクション内のドキュメントにはシャードキーのフィールドがない場合があります。シャードキーがないドキュメントを対象とするには、null を等価一致の を(_id フィールド上と同じに)別のフィルター条件と組み合わせて使用できます。以下に例を挙げます。

{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key

シャードキー フィールドが不変の _id フィールドでない限り、ドキュメントのシャードキー値を更新できます。

警告

シャーディングされたコレクション内のドキュメントには、シャード キー フィールドがないことがあります。ドキュメントのシャード キーの値を変更するときに、誤ってシャード キーを削除しないように注意してください。

既存のシャードキー値をdb.collection.updateOne()で変更するには

シャーディングされたコレクションの upsert」も参照してください。

シャーディングされたコレクション内のドキュメントには、シャードキー フィールドがないことがあります。db.collection.updateOne() を使って欠落しているシャードキーを設定するには、mongos で実行する必要があります。この操作を直接シャード上で実行しないでください

さらに、次の要件も適用されます。

タスク
要件
設定するには null
  • upsert: trueの場合は、シャード キー全体に等価フィルターが必要です。

null以外の値に設定するには

Tip

欠落しているキー値は NULL 等価一致の一部として返されるため、NULL 値のキーが更新されないように、必要に応じて追加のクエリ条件(_id フィールドなど)を追加します。

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

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

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

重要

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

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

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

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

Tip

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

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

db.collection.updateOne() 操作によってドキュメントが正常に更新されると、その操作によって oplog(操作ログ)にエントリーが追加されます。操作が失敗した場合、または更新するドキュメントが見つからなかった場合は、その操作によって oplog にエントリーが追加されることはありません。

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

{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan" },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 0 }

次の操作は、 name: "Central Perk Cafe"violationsフィールドで単一のドキュメントを更新します。

try {
db.restaurant.updateOne(
{ "name" : "Central Perk Cafe" },
{ $set: { "violations" : 3 } }
);
} catch (e) {
print(e);
}

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

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

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

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

upsert: trueを設定すると、一致するものが見つからない場合にはドキュメントが挿入されます。 「アップサートによる更新 」を参照してください。

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

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

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

次のドキュメントを使用して 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, "student" : "Elizabeth", "points" : 60, "commentsSemester1" : "well behaved", "commentsSemester2" : "needs improvement", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }
] )

最初のドキュメントで commentsSemester1 フィールドと commentsSemester2 フィールドを分ける代わりに、2 番目のドキュメントのように comments フィールドにまとめたいと仮定します。次の更新操作では、集計パイプラインを使用して操作を行います。

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

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

Update コマンドのフィルターが一意のドキュメントをターゲットにしていることを確認してください。以下のコードの id フィールドは、そのようなフィルターの例です。

db.students.updateOne(
{ _id: 1 },
[
{ $set: { status: "Modified", comments: [ "$commentsSemester1", "$commentsSemester2" ], lastUpdate: "$$NOW" } },
{ $unset: [ "commentsSemester1", "commentsSemester2" ] }
]
)

注意

パイプライン内で使用される $set$unset は、集計ステージの$set$unset をそれぞれ示しており、アップデートの演算子の$set$unset ではありません。

第 1 ステージ

$set段階:

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

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

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

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

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

ソートを導入すると、ソート順で最初に見つかったドキュメントのみが変更され、残りのドキュメントはそのままにされることに注意してください。

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

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

db.students3.insertMany( [
{ "_id" : 1, "tests" : [ 95, 92, 90 ], "average" : 92, "grade" : "A", "lastUpdate" : ISODate("2020-01-23T05:18:40.013Z") },
{ "_id" : 2, "tests" : [ 94, 88, 90 ], "average" : 91, "grade" : "A", "lastUpdate" : ISODate("2020-01-23T05:18:40.013Z") },
{ "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }
] )

3 番目のドキュメント_id: 3には、 averageフィールドとgradeフィールドがありません。集計パイプラインを使用して、計算された成績の平均およびレターグレードでドキュメントを更新することができます。

db.students3.updateOne(
{ _id: 3 },
[
{ $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は、アップデートオペレーターの $set ではなく、集計ステージ $setを参照します。

第 1 ステージ

$set段階:

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

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

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

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

{ "_id" : 1, "tests" : [ 95, 92, 90 ], "average" : 92, "grade" : "A", "lastUpdate" : ISODate("2020-01-23T05:18:40.013Z") }
{ "_id" : 2, "tests" : [ 94, 88, 90 ], "average" : 91, "grade" : "A", "lastUpdate" : ISODate("2020-01-23T05:18:40.013Z") }
{ "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2020-01-24T17:33:30.674Z"), "average" : 75, "grade" : "C" }

Tip

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

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

{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : "0" }

次の操作は、upsert: trueの間にname : "Pizza Rat's Pizzaria"を使用してドキュメントを更新しようとしています。

try {
db.restaurant.updateOne(
{ "name" : "Pizza Rat's Pizzaria" },
{ $set: {"_id" : 4, "violations" : 7, "borough" : "Manhattan" } },
{ upsert: true }
);
} catch (e) {
print(e);
}

upsert:trueなので、ドキュメントはfilterおよびupdate基準に基づいてinsertedになります。この操作では以下を返します。

{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : 4,
"upsertedCount": 1
}

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

{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 4 },
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "Borough" : "Manhattan", "violations" : 7 }

name フィールドは filter 基準を使用して入力され、update 演算子を使用してドキュメントの残りの部分が作成されました。

次の操作では、10より大きいviolationsを持つ最初のドキュメントを更新します。

try {
db.restaurant.updateOne(
{ "violations" : { $gt: 10} },
{ $set: { "Closed" : true } },
{ upsert: true }
);
} catch (e) {
print(e);
}

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

{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("56310c3c0c5cbb6031cafaea")
}

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

{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 4 },
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "Borough" : "Manhattan", "grade" : 7 }
{ "_id" : ObjectId("56310c3c0c5cbb6031cafaea"), "Closed" : true }

フィルターに一致するドキュメントがなく、 upserttrueであったため、 updateOne()は生成された_idupdate条件のみを持つドキュメントを挿入しました。

3 つのノードからなるレプリカセットがある場合、次の操作では majorityw と、100wtimeout と指定します。

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

プライマリと少なくとも 1 つのセカンダリが 100 ミリ秒以内に各書き込み操作を確認すると、次の値が返されます。

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

承認に 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.updateOne(
{ 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>]db.collection.updateOne()メソッドでarrayFiltersオプションとともに使用します。

db.students.updateOne(
{ grades: { $gte: 100 } },
{ $set: { "grades.$[element]" : 100 } },
{ arrayFilters: [ { "element": { $gte: 100 } } ] }
)

この操作により 1 つのドキュメントの grades フィールドが更新され、操作後にコレクションには次のドキュメントが含まれます。

{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 100 ] }
{ "_id" : 3, "grades" : [ 95, 110, 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.collection.updateOne() メソッドで使用します。

db.students2.updateOne(
{ },
{ $set: { "grades.$[elem].mean" : 100 } },
{ arrayFilters: [ { "elem.grade": { $gte: 85 } } ] }
)

この操作により 1 つのドキュメントの配列が更新され、操作後にコレクションには次のドキュメントが含まれます。

{
"_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" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "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 } )
db.students.createIndex( { points: 1 } )

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

注意

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

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

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

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

注意

3 つのドキュメントが更新の基準に一致しているにもかかわらず、updateOneは、最初に見つけたドキュメントのみを変更します。したがって、リチャード、ロナン、アダムのすべての学生が基準を満たしていても、リチャードだけが更新されます。

使用されたインデックスを確認するには、次の操作で explain を実行します。

db.students.explain().update(
{ "points": { $lte: 20 }, "grade": "F" },
{ $set: { "comments1": "failed class" } },
{ multi: true, hint: { 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 one document
db.medical.updateOne( {
// User must have the Provider role to perform the update
$expr: { $ne: [
{ $setIntersection: [ [ "Provider" ], "$$USER_ROLES.role" ] }, []
] } },
// Update diagnosisCode
{ $set: { diagnosisCode: "ACH 01"} }
)

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

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

1

実行:

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

実行:

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

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

Tip

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

複数のドキュメントを更新する方法については、db.collection.updateMany()を参照してください。

戻る

db.collection.updateMany