db.collection.findOneAndReplace()
MongoDB とドライバー
このページでは、 mongosh
メソッドについて説明します。MongoDB ドライバーで同等のメソッドを確認するには、ご使用のプログラミング言語の対応するページを参照してください。
定義
db.collection.findOneAndReplace( filter, replacement, options )
指定されたフィルターに基づいて単一のドキュメントを置き換えます。
互換性
このメソッドは、次の環境でホストされている配置で使用できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
注意
このコマンドは、すべての MongoDB Atlas クラスターでサポートされています。すべてのコマンドに対する Atlas のサポートについては、「サポートされていないコマンド」を参照してください。
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
構文
findOneAndReplace()
メソッドの形式は次のとおりです。
db.collection.findOneAndReplace( <filter>, <replacement>, { writeConcern: <document>, projection: <document>, sort: <document>, maxTimeMS: <number>, upsert: <boolean>, returnDocument: <string>, returnNewDocument: <boolean>, collation: <document> } )
フィールドとオプション
findOneAndReplace()
メソッドは次のフィールドとオプションを取ります。
フィールド | タイプ | 説明 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
ドキュメント | ||||||||||||
ドキュメント | ||||||||||||
writeConcern | ドキュメント | 任意。書込み保証(write concern)を表現するドキュメント。デフォルトの書込み保証を使用する場合は省略します。
トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。 | ||||||||||
ドキュメント | 任意。返すフィールドのサブセット。 一致するドキュメント内のすべてのフィールドを返すには、このフィールドを省略します。 プロジェクションの引数がドキュメントでない場合、操作はエラーになります。 | |||||||||||
ドキュメント | ||||||||||||
maxTimeMS | 数値 | オプション。操作が完了するまでの制限時間をミリ秒単位で指定します。制限を超えた場合はエラーを返します。 | ||||||||||
ブール値 | 任意。
MongoDB では、 複数のアップサートを回避するため、 デフォルトは | |||||||||||
string | オプション。
| |||||||||||
ブール値 | オプション。 デフォルトは | |||||||||||
ドキュメント | 任意。 操作に使用する照合を指定します。 照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。 照合オプションの構文は次のとおりです。
照合を指定する場合、 照合が指定されていなくても、コレクションにデフォルトの照合が設定されている場合( コレクションにも操作にも照合が指定されていない場合、MongoDB では以前のバージョンで使用されていた単純なバイナリ比較によって文字列が比較されます。 1 つの操作に複数の照合は指定できません。たとえば、フィールドごとに異なる照合を指定できません。また、ソートと検索を一度に実行する場合、検索とソートで別の照合を使用できません。 |
戻り値
デフォルトでは元のドキュメントを返します。 returnDocumentがafter
またはreturnNewDocumentがtrue
に設定されている場合、更新されたドキュメントを返します。
動作
ドキュメント一致
db.collection.findOneAndReplace()
は、 filter
に一致するコレクション内の最初に一致するドキュメントを置き換えます。 sort
フィールドを使用して、どのドキュメントを変更するか制御できます。
プロジェクション
重要
言語の整合性
find()
とfindAndModify()
のプロジェクションを集計の$project
ステージと一貫性を持たせるために、
find()
とfindAndModify()
のプロジェクションは集計式と構文 を受け付けます。MongoDB は、プロジェクションに関して追加の制限を適用します。詳細については、「プロジェクションの制限」を参照してください。
projection
フィールドは次の形式のドキュメントを受け取ります。
{ field1: <value>, field2: <value> ... }
プロジェクション | 説明 |
---|---|
<field>: <1 or true> | フィールドを包含することを指定します。プロジェクションの値としてゼロ以外の整数を指定した場合、その値を true として処理します。 |
<field>: <0 or false> | フィールドの除外を指定します。 |
"<field>.$": <1 or true> | |
<field>: <array projection> | 配列プロジェクション 演算子( ビューには使用できません。 |
<field>: <aggregation expression> | プロジェクションを行ったフィールドの値を指定します。 集計式と構文の使用(リテラルと集計変数の使用を含む)では、新しいフィールドをプロジェクションしたり、既存のフィールドを新しい値でプロジェクションしたりできます。
|
埋め込みフィールド仕様
埋め込みドキュメント内のフィールドの場合は、次のいずれかを使用してフィールドを指定できます。
ドット表記の場合は次のようになります。
"field.nestedfield": <value>
ネストされた形式の例
{ field: { nestedfield: <value> } }
_id
フィールドプロジェクション
_id
フィールドは、プロジェクションで _id: 0
を明示的に指定して抑制しない限り、返されるドキュメントにデフォルトで含まれます。
包含または除外
projection
には、 _id
フィールドを除いて、包含指定と除外指定の両方を含めることはできません。
フィールドを明示的に含めるプロジェクションでは、
_id
フィールドだけが明示的に除外できる唯一のフィールドです。フィールドを明示的に除外するプロジェクションでは、
_id
フィールドが明示的に包含できる唯一のフィールドですが、デフォルトで_id
フィールドが含まれます。
プロジェクションの詳細については、以下も参照してください。
シャーディングされたコレクション
シャーディングされたコレクションでdb.collection.findOneAndReplace()
を使用するには、クエリフィルターにシャードキーの等価条件が含まれている必要があります。
シャーディングされたコレクション内のドキュメントには、シャードキー フィールドがない場合があります。シャードキーがないドキュメントを対象とするには、null
の等価一致を別のフィルター条件(_id
フィールド上と同様に)と組み合わせて使用できます。例:
{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key
シャードキーの変更
シャードキー フィールドが不変の _id
フィールドでない限り、ドキュメントのシャードキー値を更新できます。
警告
シャーディングされたコレクション内のドキュメントには、シャード キー フィールドがないことがあります。ドキュメントのシャード キーの値を変更するときに、誤ってシャード キーを削除しないように注意してください。
既存のシャードキー値をdb.collection.findOneAndReplace()
で変更するには
必ず
mongos
上で使用します。シャードに直接操作を実行しないでください。トランザクション内で、または 再試行可能な書き込みとして実行する必要があります。
完全なシャードキーに等価フィルターを含める必要があります。
欠落しているシャードキー
シャーディングされたコレクション内のドキュメントには、 シャードキー フィールドがない場合があります 。 To use db.collection.findOneAndReplace()
to set the document's missing shard key,
必ず
mongos
上で使用します。シャードに直接操作を実行しないでください。新しいシャードキー値が
null
でない場合は、トランザクション内で実行するか、再試行可能な書き込みとして実行する必要があります。完全なシャードキーに等価フィルターを含める必要があります。
Tip
欠落しているキー値は NULL 等価一致の一部として返されるため、NULL 値のキーが更新されないように、必要に応じて追加のクエリ条件(_id
フィールドなど)を追加します。
以下も参照してください。
トランザクション
db.collection.findOneAndReplace()
は分散トランザクション内で使用できます。
重要
ほとんどの場合、分散トランザクションでは 1 つのドキュメントの書き込み (write) よりもパフォーマンス コストが高くなります。分散トランザクションの可用性は、効果的なスキーマ設計の代わりにはなりません。多くのシナリオにおいて、非正規化されたデータモデル(埋め込みドキュメントと配列)が引き続きデータやユースケースに最適です。つまり、多くのシナリオにおいて、データを適切にモデリングすることで、分散トランザクションの必要性を最小限に抑えることができます。
トランザクションの使用に関するその他の考慮事項(ランタイム制限や oplog サイズ制限など)については、「本番環境での考慮事項」も参照してください。
トランザクション内のアップサート
トランザクションがクロスシャード間書き込みトランザクション(write transaction)でない場合に、分散トランザクション内にコレクションとインデックスを作成できます。
db.collection.findOneAndReplace()
と upsert: true
は、既存のコレクションまたは存在しないコレクションで実行できます。存在しないコレクションに対して実行すると、操作によってコレクションが作成されます。
書込み保証とトランザクション
トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。
Oplog エントリ
db.collection.findOneAndReplace()
操作によってドキュメントが正常に置き換えられると、その操作によってoplog (操作ログ)にエントリが追加されます。 操作が失敗した場合、または置き換えるドキュメントが見つからなかった場合は、その操作によって oplog にエントリーが追加されることはありません。
例
ドキュメントの置換
次のドキュメントを使用してサンプルscores
コレクションを作成します。
db.scores.insertMany([ { "_id" : 1, "team" : "Fearful Mallards", "score" : 25000 }, { "_id" : 2, "team" : "Tactful Mooses", "score" : 23500 }, { "_id" : 3, "team" : "Aquatic Ponies", "score" : 19250 }, { "_id" : 4, "team" : "Cuddly Zebras", "score" : 15235 }, { "_id" : 5, "team" : "Garrulous Bears", "score" : 18000 } ]);
次の操作は、 score
が20000
より小さいドキュメントを検索して以下に置き換えます。
db.scores.findOneAndReplace( { "score" : { $lt : 20000 } }, { "team" : "Observant Badgers", "score" : 20000 } )
この操作は、置き換えられた元の文書を返します。
{ "_id" : 3, "team" : "Aquatic Ponies", "score" : 19250 }
returnNewDocument が true の場合、操作は代わりに置換ドキュメントを返します。
複数のドキュメントがフィルタ条件を満たしていますが、 db.collection.findOneAndReplace()
は 1 つのドキュメントのみを置換します。
ドキュメントのソートと置換
次のドキュメントを使用してサンプルscores
コレクションを作成します。
db.scores.insertMany([ { "_id" : 1, "team" : "Fearful Mallards", "score" : 25000 }, { "_id" : 2, "team" : "Tactful Mooses", "score" : 23500 }, { "_id" : 3, "team" : "Aquatic Ponies", "score" : 19250 }, { "_id" : 4, "team" : "Cuddly Zebras", "score" : 15235 }, { "_id" : 5, "team" : "Garrulous Bears", "score" : 18000 } ]);
次の例では、 score
フィールドに昇順ソートを含めることで、フィルターに一致するドキュメントの中でスコアが最も低いドキュメントを置換します。
db.scores.findOneAndReplace( { "score" : { $lt : 20000 } }, { "team" : "Observant Badgers", "score" : 20000 }, { sort: { "score" : 1 } } )
この操作は、置き換えられた元の文書を返します。
{ "_id" : 4, "team" : "Cuddly Zebras", "score" : 15235 }
このコマンドのソートされていない結果については、「ドキュメントの置換」を参照してください。
返されるドキュメント内のプロジェクト固有のフィールド
次のドキュメントを使用してサンプルscores
コレクションを作成します。
db.scores.insertMany([ { "_id" : 1, "team" : "Fearful Mallards", "score" : 25000 }, { "_id" : 2, "team" : "Tactful Mooses", "score" : 23500 }, { "_id" : 3, "team" : "Aquatic Ponies", "score" : 19250 }, { "_id" : 4, "team" : "Cuddly Zebras", "score" : 15235 }, { "_id" : 5, "team" : "Garrulous Bears", "score" : 18000 } ])
次の操作では、プロジェクションを使用して、返されたドキュメントのteam
フィールドのみを表示します。
db.scores.findOneAndReplace( { "score" : { $lt : 22250 } }, { "team" : "Therapeutic Hamsters", "score" : 22250 }, { sort : { "score" : 1 }, projection: { "_id" : 0, "team" : 1 } } )
この操作では、 team
フィールドのみを含む元のドキュメントが返されます。
{ "team" : "Cuddly Zebras" }
ドキュメントを時間制限付きで置換
次の操作では、完了までに 5 ミリ秒の時間制限が設定されます。
try { db.scores.findOneAndReplace( { "score" : { $gt : 25000 } }, { "team" : "Emphatic Rhinos", "score" : 25010 }, { maxTimeMS: 5 } ); } catch(e){ print(e); }
操作が時間制限を超えた場合、以下が返されます。
Error: findAndModifyFailed failed: { "ok" : 0, "errmsg" : "operation exceeded time limit", "code" : 50 }
アップサートによるドキュメント置換
次の操作では、フィルターに一致するドキュメントがない場合に、アップサートフィールドを使用して置換ドキュメントを挿入します。
try { db.scores.findOneAndReplace( { "team" : "Fortified Lobsters" }, { "_id" : 6019, "team" : "Fortified Lobsters" , "score" : 32000}, { upsert : true, returnDocument: "after" } ); } catch (e){ print(e); }
この操作では、以下を返します。
{ "_id" : 6019, "team" : "Fortified Lobsters", "score" : 32000 }
returnDocument: "before"
が設定されている場合、元のドキュメントがないため、操作はnull
を返します。
照合の指定
照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。
次のドキュメントを使用してサンプルmyColl
コレクションを作成します。
db.myColl.insertMany([ { _id: 1, category: "café", status: "A" }, { _id: 2, category: "cafe", status: "a" }, { _id: 3, category: "cafE", status: "a" } ]);
次の操作には照合オプションが含まれます。
db.myColl.findOneAndReplace( { category: "cafe", status: "a" }, { category: "cafÉ", status: "Replaced" }, { collation: { locale: "fr", strength: 1 } } );
この操作を実行すると次のドキュメントが返されます。
{ "_id" : 1, "category" : "café", "status" : "A" }