findAndModify
定義
findAndModify
findAndModify
コマンドは 1 つのドキュメントを更新して返します。デフォルトでは、返されるドキュメントには更新時に行われた変更は含まれません。更新時に行われた変更を含むドキュメントを返すには、new
オプションを使用します。Tip
mongosh
では、このコマンドはdb.collection.findAndModify()
ヘルパー メソッドを通じて実行することもできます。ヘルパー メソッドは
mongosh
ユーザーには便利ですが、データベースコマンドと同じレベルの情報は返されない可能性があります。 便宜上必要ない場合、または追加の戻りフィールドが必要な場合は、 データベースコマンドを使用します。
互換性
このコマンドは、次の環境でホストされている配置で使用できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
注意
このコマンドは、すべての MongoDB Atlas クラスターでサポートされています。すべてのコマンドに対する Atlas のサポートについては、「サポートされていないコマンド」を参照してください。
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
バージョン5.0での変更:このコマンドの構文は、次のとおりです。
{ findAndModify: <collection-name>, query: <document>, sort: <document>, remove: <boolean>, update: <document or aggregation pipeline>, new: <boolean>, fields: <document>, upsert: <boolean>, bypassDocumentValidation: <boolean>, writeConcern: <document>, maxTimeMS: <integer>, collation: <document>, arrayFilters: <array>, hint: <document|string>, comment: <any>, let: <document> // Added in MongoDB 5.0 }
findAndModify
コマンドは、次のフィールドを取ります。
フィールド | タイプ | 説明 | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
query | ドキュメント | 任意。変更操作の選択基準。 指定しない場合、デフォルトは空のドキュメントになります。 クエリ引数がドキュメントでない場合、操作はエラーになります。 | ||||||||||||||||||
| ドキュメント | 任意。クエリで複数のドキュメントが選択された場合に、その操作で更新するドキュメントを決定します。 ソート引数がドキュメントでない場合、操作はエラーになります。 MongoDB では、コレクション内のドキュメントを特定の順序で保存することはありません。重複する値を含むフィールドでソートする場合、それらの値を含むドキュメントは任意の順序で返されます。 一貫したソート順序が必要な場合は、一意の値を含むフィールドを少なくとも 1 つ含めてソートしてください。これを保証する最も簡単な方法は、 詳細については、「ソートの整合性」を参照してください。 | ||||||||||||||||||
remove | ブール値 | remove フィールドまたは update フィールドのいずれかを指定する必要があります。query フィールドで指定されたドキュメントを削除します。選択したドキュメントを削除するには、これを true に設定します。デフォルト値は false です。 | ||||||||||||||||||
update | ドキュメントまたは配列 |
| ||||||||||||||||||
new | ブール値 | 任意。 true の場合、元のドキュメントではなく更新されたドキュメントを返します。デフォルト値は false です。 | ||||||||||||||||||
fields | ドキュメント | 任意。返すフィールドのサブセット。 フィールド引数がドキュメントでない場合、操作はエラーになります。 | ||||||||||||||||||
upsert | ブール値 | 任意。
複数のアップサートを回避するため、 デフォルトは | ||||||||||||||||||
bypassDocumentValidation | ブール値 | 任意。 操作中に findAndModify がドキュメント検証をバイパスできるようにします。 これにより、検証要件を満たさないドキュメントを更新できるようになります。 | ||||||||||||||||||
writeConcern | ドキュメント | 任意。書込み保証(write concern)を表現するドキュメント。デフォルトの書込み保証を使用する場合は省略します。 トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。 | ||||||||||||||||||
maxTimeMS | non-negative integer | 任意。 時間制限をミリ秒単位で指定します。 MongoDB は、 | ||||||||||||||||||
findAndModify | string | コマンドを実行するコレクション。 | ||||||||||||||||||
collation | ドキュメント | 任意。 操作に使用する照合を指定します。 照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。 照合オプションの構文は次のとおりです。
照合を指定する場合、 照合が指定されていなくても、コレクションにデフォルトの照合が設定されている場合( コレクションにも操作にも照合が指定されていない場合、MongoDB では以前のバージョンで使用されていた単純なバイナリ比較によって文字列が比較されます。 1 つの操作に複数の照合は指定できません。たとえば、フィールドごとに異なる照合を指定できません。また、ソートと検索を一度に実行する場合、検索とソートで別の照合を使用できません。 バージョン 3.4 で追加。 | ||||||||||||||||||
arrayFilters | 配列 | 任意。配列フィールドの更新操作でどの配列要素を変更するかを決定するフィルター ドキュメントの配列。 アップデート ドキュメントでは、
アップデート ドキュメントには同じ識別子を複数回含めることができます。ただし、アップデート ドキュメント内の個別の識別子 (
ただし、次の例のように、単一のフィルター ドキュメント内の同じ識別子に複合条件を指定できます。
例については、
| ||||||||||||||||||
hint | ドキュメントまたは文字列 | 任意。 このオプションには、インデックス仕様ドキュメントまたはインデックス名の文字列を指定できます。 存在しないインデックスを指定した場合、操作はエラーになります。 例については、「 | ||||||||||||||||||
comment | any | 任意。このコマンドに添付するユーザー指定のコメント。設定すると、このコメントは以下の場所にこのコマンドの記録と合わせて表示されます。
コメントには、有効な BSON 型(string, integer, object, array など)を使用できます。 | ||||||||||||||||||
ドキュメント | 任意。 変数のリストを含むドキュメントを指定します。これにより、変数をクエリテキストから分離することで、コマンドの読みやすさを向上させることができます。 ドキュメントの構文は次のとおりです。
変数は式によって返された値に設定され、その後は変更できません。 コマンド内の変数の値にアクセスするには、二重ドル記号の接頭辞( 結果のフィルタリングに変数を使用するには、
バージョン 5.0 で追加 |
出力
findAndModify
コマンドは、次のフィールドを含むドキュメントを返します。
フィールド | タイプ | 説明 |
---|---|---|
value | ドキュメント | コマンドの戻り値が含まれます。詳しくは、 value を参照してください。 |
lastErrorObject | ドキュメント | 更新されたドキュメントに関する情報が含まれます。詳しくは、 lastErrorObject を参照してください。 |
ok | 数値 | コマンドの実行状態が入ります。成功した場合は 1 、エラーが発生した場合は 0 になります。 |
lastErrorObject
lastErrorObject
埋め込みドキュメントには、次のフィールドが含まれています。
フィールド | タイプ | 説明 |
---|---|---|
updatedExisting | ブール値 |
|
upserted | ドキュメント |
value
remove
操作では、クエリがドキュメントと一致する場合、value
には削除されたドキュメントが入ります。クエリが削除するドキュメントと一致しない場合、value
には null
が入ります。
update
操作の場合、value
埋め込みドキュメントには次の内容が含まれます。
new
パラメーターがセットされていないか、false
の場合クエリがドキュメントにマッチした場合、変更前のドキュメント。
それ以外の場合は、
null
。
new
がtrue
の場合クエリが一致を返した場合、更新されたドキュメント。
upsert: true
でクエリに一致するドキュメントがない場合、挿入されたドキュメント。それ以外の場合は、
null
。
動作
一意なインデックスを使用したアップサート
重複を防ぐためのユニークインデックスがない限り、アップサートによって重複したドキュメントが作成されることがあります。
Andy
という名前のドキュメントが存在せず、複数のクライアントがほぼ同時に次のコマンドを発行する例を考えます。
db.runCommand( { findAndModify: "people", query: { name: "Andy" }, update: { $inc: { score: 1 } }, upsert: true } )
いずれかのクライアントがデータを正常に挿入する前にすべての findAndModify
操作がクエリ フェーズを終了し、かつ name
フィールドにユニークインデックスがない場合、各 findAndModify
操作によって挿入が行われて、name: Andy
を含む複数のドキュメントが作成される可能性があります。
name
フィールドに一意なインデックスを設定すると、ドキュメントが 1 つだけ作成されるようになります。一意なインデックスが設定されると、複数の findAndModify
操作で次の動作が見られるようになります。
正確に 1 つの
findAndModify
操作で新しいドキュメントが正常に挿入されます。その他の
findAndModify
操作は、新しく挿入されたドキュメントを更新するか、一意なキーの競合が原因で失敗します。他の
findAndModify
操作で新しく挿入されたドキュメントを更新するには、次の条件がすべて満たされている必要があります。ターゲット コレクションに一意なインデックスがあるため、重複キー エラーが発生。
更新操作が
updateMany
ではない、またはmulti
がfalse
。アップデートの一致条件は、次のいずれかです。
単一の等価述語。例:
{ "fieldA" : "valueA" }
等価述語の論理 AND。例:
{ "fieldA" : "valueA", "fieldB" : "valueB" }
等価述語内のフィールドが、一意なインデックス キー パターン内のフィールドと一致。
更新操作が、一意なインデックス キー パターン内のフィールドを変更しない。
次の表に示す upsert
操作の例では、キーの衝突が発生した場合に更新されるか失敗します。
ユニークインデックスキーのパターン | アップデート操作 | 結果 | ||||||
---|---|---|---|---|---|---|---|---|
|
| マッチしたドキュメントの score フィールドが 1 インクリメントされます。 | ||||||
|
| 一意なインデックス キー パターン( name )のフィールドが変更されるため、操作は失敗します。 | ||||||
|
| 等式述語フィールド( name 、email )がインデックス キー フィールド(name )と一致しないため、操作は失敗します。 |
シャーディングされたコレクション
シャーディングされたコレクションでfindAndModify
を使用するには、次の手順に従います。
1つのシャードのみをターゲットにする場合は、
query
フィールドで部分的なシャードキーを使用できます。またはquery
フィールドの完全なシャードキーに等価条件を指定できます。
シャーディングされたコレクション内のドキュメントには、シャードキー フィールドがない場合があります。シャードキーがないドキュメントをターゲットにするには、null
等価一致を別のフィルター条件(_id
フィールドなど)と組み合わせて使用できます。以下に例を挙げます。
{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key
シャードキーの変更
シャードキー フィールドが不変の _id
フィールドでない限り、ドキュメントのシャードキー値を更新できます。
警告
シャーディングされたコレクション内のドキュメントには、シャード キー フィールドがないことがあります。ドキュメントのシャード キーの値を変更するときに、誤ってシャード キーを削除しないように注意してください。
既存のシャードキー値をfindAndModify
で更新する方法:
必ず
mongos
上で使用します。シャードに直接操作を実行しないでください。トランザクション内で、または 再試行可能な書き込みとして実行する必要があります。
完全なシャードキーに等価フィルターを含める必要があります。
欠落しているシャードキー
シャーディングされたコレクション内のドキュメントには、シャードキー フィールドがない場合があります。findAndModify
を使用してドキュメントにないシャードキーを設定するには、以下が必要です。
必ず
mongos
上で使用します。シャードに直接操作を実行しないでください。新しいシャードキー値が
null
でない場合は、トランザクション内で実行するか、再試行可能な書き込みとして実行する必要があります。完全なシャードキーに等価フィルターを含める必要があります。
Tip
欠落しているキー値は NULL 等価一致の一部として返されるため、NULL 値のキーが更新されないように、必要に応じて追加のクエリ条件(_id
フィールドなど)を追加します。
以下も参照してください。
ドキュメントの検証
findAndModify
コマンドはbypassDocumentValidation
オプションのサポートを追加します。これにより、検証ルールを使用してコレクションにドキュメントを挿入または更新するときにドキュメント検証をバイパスできます。
update
メソッドとの比較
ドキュメントを更新する場合の findAndModify
メソッドと updateOne()
メソッドの動作は異なります。
更新条件に一致するドキュメントが複数ある場合、
findAndModify
では、sort
を指定することで、更新するドキュメントの選択に関して一定の制御が可能です。updateOne()
は一致する最初のドキュメントを更新します。デフォルトでは、
findAndModify
で、変更前のドキュメントと操作のステータスが含まれたオブジェクトが返されます。更新済みのドキュメントを取得するには、new
オプションを使用します。updateOne()
メソッドは、操作のステータスを含むWriteResult()
オブジェクトを返します。更新されたドキュメントを返すには、
find()
メソッドを使用します。ただし、更新してからドキュメントを取得するまでの間に、他の更新によってドキュメントが変更される可能性があります。また、更新によって 1 つのドキュメントのみが変更されたが、複数のドキュメントが一致した場合は、更新されたドキュメントを識別するために追加のロジックを使用する必要があります。
1 つのドキュメントを変更する場合、findAndModify
メソッドと updateOne()
メソッドの両方でドキュメントがアトミックに更新されます。これらのメソッドの相互作用と操作順序の詳細については、「アトミック性とトランザクション」を参照してください。
トランザクション
findAndModify
は分散トランザクション内で使用できます。
重要
ほとんどの場合、分散トランザクションでは 1 つのドキュメントの書き込み (write) よりもパフォーマンス コストが高くなります。分散トランザクションの可用性は、効果的なスキーマ設計の代わりにはなりません。多くのシナリオにおいて、非正規化されたデータモデル(埋め込みドキュメントと配列)が引き続きデータやユースケースに最適です。つまり、多くのシナリオにおいて、データを適切にモデリングすることで、分散トランザクションの必要性を最小限に抑えることができます。
トランザクションの使用に関するその他の考慮事項(ランタイム制限や oplog サイズ制限など)については、「本番環境での考慮事項」も参照してください。
トランザクション内のアップサート
トランザクションがクロスシャード間書き込みトランザクション(write transaction)でない場合に、分散トランザクション内にコレクションとインデックスを作成できます。
findAndModify
と upsert: true
は、既存のコレクションまたは存在しないコレクションで実行できます。存在しないコレクションに対して実行すると、操作によってコレクションが作成されます。
書込み保証とトランザクション
トランザクションで実行される場合、操作の書込み保証 (write concern)を明示的に設定しないでください。トランザクションで書込み保証を使用するには、「トランザクション書込み保証」を参照してください。
例
更新と返却
次のコマンドは、people
コレクション内の既存のドキュメントで、ドキュメントが query
条件に一致するものを更新します。
db.runCommand( { findAndModify: "people", query: { name: "Tom", state: "active", rating: { $gt: 10 } }, sort: { rating: 1 }, update: { $inc: { score: 1 } } } )
このコマンドは、次のアクションを実行します。
query
は、name
フィールドの値がTom
、state
フィールドの値がactive
、rating
フィールドの値がgreater than
10 であるドキュメントをpeople
コレクション内で検索します。sort
は、クエリの結果を昇順に並べます。複数のドキュメントがquery
条件を満たす場合、コマンドはこのsort
の順序に従って最初のドキュメントを変更対象として選択します。update
はscore
フィールドの値を 1 ずつincrements
します。このコマンドは、次のフィールドを含むドキュメントを返します。
コマンドの詳細を含む
lastErrorObject
フィールド(true
であるフィールドupdatedExisting
を含む)とこの更新で選択された元の(つまり、変更前の)ドキュメントを含む
value
値フィールド{ "lastErrorObject" : { "connectionId" : 1, "updatedExisting" : true, "n" : 1, "syncMillis" : 0, "writtenTo" : null, "err" : null, "ok" : 1 }, value" : { "_id" : ObjectId("54f62d2885e4be1f982b9c9c"), "name" : "Tom", "state" : "active", "rating" : 100, "score" : 5 }, "ok" : 1 }
更新されたドキュメントを value
フィールドに返すには、コマンドに new:true
オプションを追加します。
query
条件に一致するドキュメントがない場合、コマンドは value
フィールドに null
を含むドキュメントを返します。
{ "value" : null, "ok" : 1 }
mongosh
および多くのドライバーでは findAndModify()
ヘルパー メソッドを提供します。シェルヘルパーを使用すると、前述の操作は次の形式になります。
db.people.findAndModify( { query: { name: "Tom", state: "active", rating: { $gt: 10 } }, sort: { rating: 1 }, update: { $inc: { score: 1 } } } );
ただし、findAndModify()
シェルヘルパー メソッドは変更されていないドキュメントのみを返します。または、new
が true
の場合には、更新されたドキュメントを返します。
{ "_id" : ObjectId("54f62d2885e4be1f982b9c9c"), "name" : "Tom", "state" : "active", "rating" : 100, "score" : 5 }
upsert: true
次の findAndModify
コマンドには、update
操作の upsert:
true
オプションが含まれおり、一致するドキュメントをアップデートするか、一致するドキュメントが存在しない場合は新しいドキュメントを作成します。
db.runCommand( { findAndModify: "people", query: { name: "Gus", state: "active", rating: 100 }, sort: { rating: 1 }, update: { $inc: { score: 1 } }, upsert: true } )
コマンドが一致するドキュメントを見つけた場合、コマンドは更新を実行します。
一致するドキュメントが見つからない場合、upsert: true の update
操作によって挿入が行われ、次のフィールドを含むドキュメントが返されます。
コマンドの詳細を含む
lastErrorObject
フィールド(新しく挿入されたドキュメントの_id
値を含むフィールドupserted
など)とnull
を含むvalue
フィールド。
{ "value" : null, "lastErrorObject" : { "updatedExisting" : false, "n" : 1, "upserted" : ObjectId("54f62c8bc85d4472eadea26f") }, "ok" : 1 }
新しいドキュメントの返却
次の findAndModify
コマンドには、upsert: true
オプションと new:true
オプションが両方含まれています。このコマンドでは、一致するドキュメントを更新して更新後のドキュメントを返すか、一致するドキュメントが存在しない場合はドキュメントを挿入して、挿入された新しいドキュメントを value
フィールドで返します。
次の例では、people
コレクション内のどのドキュメントも query
条件に一致しません。
db.runCommand( { findAndModify: "people", query: { name: "Pascal", state: "active", rating: 25 }, sort: { rating: 1 }, update: { $inc: { score: 1 } }, upsert: true, new: true } )
このコマンドは、value
フィールドに新しく挿入されたドキュメントを返します。
{ "lastErrorObject" : { "connectionId" : 1, "updatedExisting" : false, "upserted" : ObjectId("54f62bbfc85d4472eadea26d"), "n" : 1, "syncMillis" : 0, "writtenTo" : null, "err" : null, "ok" : 1 }, "value" : { "_id" : ObjectId("54f62bbfc85d4472eadea26d"), "name" : "Pascal", "rating" : 25, "state" : "active", "score" : 1 }, "ok" : 1 }
並べ替えと削除
次の例では、rating
フィールドに sort
仕様を含めることで、state
の値が active
であり、一致するドキュメントの中で最も rating
が低い 1 つのドキュメントを people
コレクションから削除します。
db.runCommand( { findAndModify: "people", query: { state: "active" }, sort: { rating: 1 }, remove: true } )
このコマンドは、次のように、削除されたドキュメントを返します。
{ "lastErrorObject" : { "connectionId" : 1, "n" : 1, "syncMillis" : 0, "writtenTo" : null, "err" : null, "ok" : 1 }, "value" : { "_id" : ObjectId("54f62a6785e4be1f982b9c9b"), "name" : "XYZ123", "score" : 1, "state" : "active", "rating" : 3 }, "ok" : 1 }
照合の指定
バージョン 3.4 で追加。
照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。
コレクション myColl
は、次のドキュメントを含みます。
{ _id: 1, category: "café", status: "A" } { _id: 2, category: "cafe", status: "a" } { _id: 3, category: "cafE", status: "a" }
次の操作には照合オプションが含まれます。
db.runCommand( { findAndModify: "myColl", query: { category: "cafe", status: "a" }, sort: { category: 1 }, update: { $set: { status: "Updated" } }, collation: { locale: "fr", strength: 1 } } )
この操作を実行すると次のドキュメントが返されます。
{ "lastErrorObject" : { "updatedExisting" : true, "n" : 1 }, "value" : { "_id" : 1, "category" : "café", "status" : "A" }, "ok" : 1 }
次を使用して配列更新操作を行います: arrayFilters
注意
arrayFilters
は、集計パイプラインが使用される更新では使用できません。
配列フィールドを更新するときに、どの配列要素を更新するかを決定するためのarrayFilters
を指定できます。
arrayFilters
条件に一致する要素を更新する
注意
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.runCommand( { findAndModify: "students", query: { grades: { $gte: 100 } }, update: { $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 ] }
ドキュメントの配列の特定の要素を更新する
注意
arrayFilters
は、集計パイプラインが使用される更新では使用できません。
次のドキュメントを使用してコレクション 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 } ] } ] )
次の操作では、_id
フィールドが 1
に等しいドキュメントを検索し、フィルター処理された位置演算子 $[<identifier>]
を arrayFilters
とともに使用して、grades
配列内で grade が 85
以上の全要素の mean
を更新します。
db.runCommand( { findAndModify: "students2", query: { _id : 1 }, update: { $set: { "grades.$[elem].mean" : 100 } }, arrayFilters: [ { "elem.grade": { $gte: 85 } } ] } )
この操作により 1 つのドキュメントの grades
フィールドが更新され、操作後にコレクションには次のドキュメントが含まれます。
{ "_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 } ] }
更新に集計パイプラインを使用
findAndModify
は、更新の集計パイプラインを受け入れることができます。このパイプラインには次のステージが含まれる可能性があります。
$addFields
およびそのエイリアス$set
$replaceRoot
とそのエイリアス$replaceWith
。
集計パイプラインを使用すると、現在のフィールド値に基づいて条件付きのアップデートを表現したり、あるフィールドを他のフィールドの値を使用してアップデートするなど、より表現内容の多いアップデート ステートメントが可能になります。
たとえば、次のドキュメントを含むコレクション 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 } ] } ] )
次の操作では、_id
フィールドが 1
に等しいドキュメントを検索し、集計パイプラインを使用して grades
フィールドから新しいフィールド total
を計算します。
db.runCommand( { findAndModify: "students2", query: { "_id" : 1 }, update: [ { $set: { "total" : { $sum: "$grades.grade" } } } ], new: true } )
操作後、コレクションには次のドキュメントが含まれます。
{ "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" :85, "std" : 6 } ], "total" : 250 } { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 75, "std" : 6 }, { "grade" : 87, "mean" : 90, "std" : 3 }, { "grade" : 85, "mean" : 85,"std" : 4 } ] }
findAndModify
操作での hint
の指定
mongosh
で、次のドキュメントを含む members
コレクションを作成します。
db.members.insertMany( [ { "_id" : 1, "member" : "abc123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }, { "_id" : 3, "member" : "lmn123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 4, "member" : "pqr123", "status" : "D", "points" : 20, "misc1" : "Deactivated", "misc2" : null }, { "_id" : 5, "member" : "ijk123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 6, "member" : "cde123", "status" : "A", "points" : 86, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" } ] )
コレクションに次のインデックスを作成します。
db.members.createIndex( { status: 1 } ) db.members.createIndex( { points: 1 } )
次の操作は、インデックス { status: 1 }
を使用することを明示的に示しています。
db.runCommand({ findAndModify: "members", query: { "points": { $lte: 20 }, "status": "P" }, remove: true, hint: { status: 1 } })
注意
存在しないインデックスを指定した場合、操作はエラーになります。
使用されたインデックスを確認するには、次の操作で explain
を実行します。
db.runCommand( { explain: { findAndModify: "members", query: { "points": { $lte: 20 }, "status": "P" }, remove: true, hint: { status: 1 } }, verbosity: "queryPlanner" } )
変数の使用 let
バージョン 5.0 で追加
コマンド内の他の場所からアクセスできる変数を定義するには let オプションを使用します。
注意
変数を使用して結果をフィルタリングするには、$expr
演算子内の変数にアクセスする必要があります。
コレクション cakeFlavors
を以下ように作成します。
db.cakeFlavors.insertMany( [ { _id: 1, flavor: "chocolate" }, { _id: 2, flavor: "strawberry" }, { _id: 3, flavor: "cherry" } ] )
次の例では、let
に targetFlavor
変数を定義し、その変数を使用してケーキのフレーバーをチェリーからオレンジに変更します。
db.cakeFlavors.runCommand( { findAndModify: db.cakeFlavors.getName(), query: { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } }, update: { flavor: "orange" }, let: { targetFlavor: "cherry" } } )