AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

db.コレクション.updateOne()(mongoshメソッド)

MongoDB とドライバー

このページでは、mongosh メソッドのドキュメントについて記載しています。MongoDB ドライバーで同等のメソッドを確認するには、ご使用のプログラミング言語の対応するページを参照してください。
db.collection.updateOne(filter, update, options)

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

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

  • MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud

注意

This command is supported in all MongoDB Atlas clusters. For information on Atlas support for all commands, see Unsupported Commands.

  • 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>,
sort: <document>,
maxTimeMS: <int>,
bypassDocumentValidation: <boolean>
}
)

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

Parameter
タイプ
説明

ドキュメント

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

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

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

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

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

upsert

ブール値

Optional. When true, updateOne() either:

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

For examples, see Specify arrayFilters for an Array Update Operations.

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

Optional. A document or string that specifies the index to use to support the query predicate.

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

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

For an example, see Specify hint for Update Operations.

let

ドキュメント

任意。

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

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

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

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

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

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

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

sort

ドキュメント

任意。

クエリで複数のドキュメントが選択された場合に、その操作で更新するドキュメントを決定します。updateOne は、この引数で指定されたソート順で、最初のドキュメントを更新します。

ソート引数がドキュメントでない場合、操作はエラーになります。

MongoDB では、コレクション内のドキュメントを特定の順序で保存することはありません。重複する値を含むフィールドでソートする場合、それらの値を含むドキュメントは任意の順序で返されます。

$sort 操作は「安定ソート」ではありません。これはソートキーと同等のドキュメントが、入力時と同じ相対的順序で出力に残ることは保証されないという意味です。

ソート条件で指定されたフィールドが2つのドキュメントに存在しない場合、それらがソートされる値は同じです。2つのドキュメントは、任意の順序で返される可能性があります。

一貫したソート順序が必要な場合は、一意の値を含むフィールドを少なくとも 1 つ含めてソートしてください。これを保証する最も簡単な方法は、_idフィールドをソートのクエリに含めることです。

詳細については、「ソートの整合性」を参照してください。

バージョン8.0の新機能。

integer

任意。タイムアウトするまでに更新操作を実行する時間制限をミリ秒単位で指定します。

ブール値

オプション。insert を有効にすると、操作中にスキーマ検証をバイパスできます。これにより、検証要件を満たさないドキュメントを挿入できるようになります。

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

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

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

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

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

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

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

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

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

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

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

db.collection.updateOne() finds the first document that matches the filter and applies the specified update modifications.

For the update specifications, the db.collection.updateOne() method can accept a document that only contains update operator expressions.

以下に例を挙げます。

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を参照してください。

For examples, see Update with Aggregation Pipeline.

  • MongoDB 8.0以降では、シャーディングされたコレクションでupsert: trueを指定する場合、フィルターに完全なシャードキーを含める必要はありません。

  • If upsert: true and no documents match the filter, db.collection.updateOne() creates a new document based on the filter criteria and update modifications. See Update with Upsert.

  • For additional db.collection.updateOne() behavior on a sharded collection, see Sharded Collections.

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

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

  • MongoDB 8.0以降では、シャーディングされたコレクションでupsert: trueを指定する場合、フィルターに完全なシャードキーを含める必要はありません。

  • If you don't specify upsert: true, you must include an exact match on the _id field or target a single shard (such as by including the shard key in the filter).

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

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

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

警告

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

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

See also upsert on a Sharded Collection.

  • バージョン7.1以降では、クエリ仕様でシャードキーまたは_idフィールドを指定する必要がありません。

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

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

    タスク
    要件

    設定するには null

    upsert: trueの場合は、シャード キー全体に等価フィルターが必要です。

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

    トランザクション 内で、または再試行可能な書き込みとして実行する必要があります。

    upsert: trueの場合は、シャード キー全体に等価フィルターが必要です。

    Tip

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

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

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

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

重要

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

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

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

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

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

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

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

db.restaurant.insertMany( [
{ _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 }

Setting upsert: true would insert the document if no match was found. See Update with Upsert

db.collection.updateOne() can use an aggregation pipeline to express a more complex update, such as a conditional update based on current field values. For the supported pipeline stages, see Update with an Aggregation Pipeline.

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

次のドキュメントを使用して 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を作成します。その要素としてcommentsSemester1フィールドとcommentsSemester2フィールドの現在の内容を含めます。

  • フィールド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" }

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

db.restaurant.insertMany( [
{ _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", violations: 7 }
{ _id: ObjectId("56310c3c0c5cbb6031cafaea"), Closed: true }

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

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

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)が一切指定されていない状態で、サーバーから発生した書き込み保証。

バージョン8.0の新機能。

次の例では、評価が最も低いアクティブなユーザーを無効化します。

db.people.updateOne(
{ state: "active" },
{ $set: { state: "inactive" } },
{ sort: { rating: 1 } }
)

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

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

db.myColl.insertMany( [
{ _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 以上の要素をすべて変更するには、db.collection.updateOne メソッドでフィルタリングした位置演算子 $[<identifier>] に 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 }
]
}
] )

グレードが 85 以上の grades 配列のすべての要素の mean フィールドの値を変更するには、db.collection.updateOne メソッドでフィルターされた位置演算子 $[<identifier>] を arrayFilters とともに使用します。

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 } }
)

バージョン8.1.2で変更。

db.collection.updateOne() がシャーディングされたクラスター内の mongos で実行されると、他のエラーが 1 つ以上発生した場合でも、レスポンスには常に writeConcernError が報告されます。以前のリリースでは、他のエラーによって db.collection.updateOne() が書込み保証 (write concern)エラーを報告しないことがあります。

例、ドキュメントが検証に失敗して DocumentValidationFailed エラーが発生し、書込み保証 (write concern)エラーも発生した場合、DocumentValidationFailed エラーと writeConcernError の両方が応答の最上位フィールドに返されます。

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 のユーザー ロールの共通部分が空ではないドキュメントを返します。Michelle はProvider のロールを持つので、更新が実行されます。

次に、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()を参照してください。