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

db.collection.findOneAndReplace()

項目一覧

  • 定義
  • 互換性
  • 構文
  • 動作

MongoDB とドライバー

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

C#Java SyncNode.jsPyMongoCC++GoJava RSKotlin CoroutineKotlin SyncPHPMongoidRustScala
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()メソッドは次のフィールドとオプションを取ります。

フィールド
タイプ
説明
ドキュメント

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

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

指定しない場合、デフォルトは空のドキュメントになります。

クエリ引数がドキュメントでない場合、操作はエラーを返します。

ドキュメント

置換ドキュメントです。

アップデート演算子を含めることはできません。

<replacement> ドキュメントでは、置換されたドキュメントと異なる _id 値を指定することはできません。

writeConcern
ドキュメント

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

{ w: <value>, j: <boolean>, wtimeout: <number> }

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

ドキュメント

任意。返すフィールドのサブセット。

一致するドキュメント内のすべてのフィールドを返すには、このフィールドを省略します。

プロジェクションの引数がドキュメントでない場合、操作はエラーになります。

ドキュメント

任意。フィルターに一致するドキュメントの並べ替え順序を指定します。

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

cursor.sort() を参照してください。

maxTimeMS
数値
オプション。操作が完了するまでの制限時間をミリ秒単位で指定します。制限を超えた場合はエラーを返します。
ブール値

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

  • filterに一致するドキュメントがない場合は、 replacementパラメータからドキュメントを挿入します。returnNewDocumenttrueでない限り、新しいドキュメントの挿入後はnullを返します。

  • filterに一致するドキュメントをreplacementドキュメントに置き換えます。

MongoDB では、filter または replacement ドキュメントで指定されていない場合、_id フィールドが置換ドキュメントに追加されます。_id が両方に存在する場合、値は等しくなければなりません。

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

デフォルトは false です。

string

オプション。mongosh 0.13.2から、returnDocumentreturnNewDocumentの代替となります。両方のオプションが設定されている場合は、 returnDocumentが優先されます。

returnDocument: "before" は元のドキュメントを返します。 returnDocument: "after"は更新されたドキュメントを返します。

ブール値

オプション。trueの場合、元のドキュメントではなく置換ドキュメントが返されます。

デフォルトは false です。

ドキュメント

任意。

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

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

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

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

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

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

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

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

デフォルトでは元のドキュメントを返します。 returnDocumentafterまたはreturnNewDocumenttrueに設定されている場合、更新されたドキュメントを返します。

db.collection.findOneAndReplace()は、 filterに一致するコレクション内の最初に一致するドキュメントを置き換えます。 sortフィールドを使用して、どのドキュメントを変更するか制御できます。

重要

言語の整合性

find()findAndModify()のプロジェクションを集計の$projectステージと一貫性を持たせるために、

projectionフィールドは次の形式のドキュメントを受け取ります。

{ field1: <value>, field2: <value> ... }
プロジェクション
説明
<field>: <1 or true>
フィールドを包含することを指定します。プロジェクションの値としてゼロ以外の整数を指定した場合、その値を true として処理します。
<field>: <0 or false>
フィールドの除外を指定します。
"<field>.$": <1 or true>

$ 配列プロジェクション 演算子を使用して、配列フィールドのクエリ条件に一致する最初の要素を返します。プロジェクションの値としてゼロ以外の整数を指定した場合、その値を true として処理します。

ビューには使用できません。

<field>: <array projection>

配列プロジェクション 演算子($elemMatch$slice)を使用して、含める配列要素を指定します。

ビューには使用できません。

<field>: <aggregation expression>

プロジェクションを行ったフィールドの値を指定します。

集計式と構文の使用(リテラルと集計変数の使用を含む)では、新しいフィールドをプロジェクションしたり、既存のフィールドを新しい値でプロジェクションしたりできます。

  • プロジェクションの値として数値でもブール値でもないリテラル(例えば、文字列リテラルや配列、演算子式)を指定すると、フィールドは新しい値でプロジェクションされます。次に例を示します。

    • { field: [ 1, 2, 3, "$someExistingField" ] }

    • { field: "New String Value" }

    • { field: { status: "Active", total: { $sum: "$existingArray" } } }

  • フィールドにリテラル値をプロジェクションするには、$literal 集計式を使用します。次に例を示します。

    • { field: { $literal: 5 } }

    • { field: { $literal: true } }

    • { field: { $literal: { fieldWithValue0: 0, fieldWithValue1: 1 } } }

埋め込みドキュメント内のフィールドの場合は、次のいずれかを使用してフィールドを指定できます。

  • ドット表記の場合は次のようになります。 "field.nestedfield": <value>

  • ネストされた形式の例 { field: { nestedfield: <value> } }

_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)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。

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

次の操作は、 score20000より小さいドキュメントを検索して以下に置き換えます。

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

戻る

db.collection.findOneAndDelete