MongoDBでは、db.collection.findAndModify()
メソッドは、単一のドキュメントを変更して返します。
collection
partは、操作を実行するコレクションの名前です。
例
pets
というコレクションがあるとします。 次のドキュメントが含まれています:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
db.collection.findAndModify()
を使用できます それらのドキュメントの1つを変更する方法。
db.pets.findAndModify({
query: { type: "Dog" },
update: { type: "Cow" }
})
結果:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" }
デフォルトでは、元のドキュメント(変更されたバージョンではありません)が返されます。
コレクションには2匹の犬がいますが、更新されたのは1匹だけであることに注意してください。
コレクションを確認しましょう。
db.pets.find()
結果:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
最初のドキュメントに犬ではなく牛が含まれていることがわかります。ただし、ドキュメントの名前フィールドが消えていることもわかります。
これは、ドキュメントをupdate
に渡すときに 引数、db.collection.findAndModify()
交換を行います。
更新演算子の使用
フィールドを更新したいが、ドキュメントの残りの部分はそのままにしておく場合は、関連する更新演算子の式をドキュメントに含める必要があります。
コレクションを現在の状態にして、別のfindAndModify()
を実行してみましょう。 これに対する操作ですが、今回は$set
を使用します 演算子を更新して、変更するフィールドだけを設定します。
db.pets.findAndModify({
query: { type: "Dog" },
update: { $set: { type: "Horse" } }
})
結果:
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
今回は残りの犬が更新されました。
コレクションを見てみましょう。
db.pets.find()
結果:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
今回は関連するフィールドが更新され、ドキュメントの残りの部分はそのまま残りました。
変更されたドキュメントを返す
デフォルトでは、db.collection.findAndModify()
を使用すると元のドキュメントが返されます 。
代わりに変更されたドキュメントを返す場合は、new
を使用してください パラメータ。
デフォルトでは、これはnew: false
です。 、その結果、元のドキュメントが返されます。ただし、new: true
を指定する 代わりに、変更されたドキュメントが返されます。
別の変更を加えましょうが、今回はnew: true
を使用します 。
db.pets.findAndModify({
query: { name: "Meow" },
update: { $set: { name: "Scratch" } },
new: true
})
結果:
{ "_id" : 3, "name" : "Scratch", "type" : "Cat" }
そこで、Meow
に名前を変更しました Scratch
へ 出力には変更が反映されます。
アップサート
upsert: true
を指定すると、アップサートを実行できます 。
アップサートは、更新操作で使用できるオプションです。指定したドキュメントが存在しない場合は、新しいドキュメントが挿入されます。 する 存在する場合、元のドキュメントが更新されます(ドキュメントは挿入されません)。
upsert: false
を使用した例
upsert: false
のときに、存在しないドキュメントを更新しようとする例を次に示します。 。
db.pets.findAndModify({
query: { _id: 4 },
update: { _id: 4, name: "Fetch", type: "Dog" },
new: true
})
結果:
null
ドキュメントがコレクションに存在しなかったため、findAndModify()
返されたnull
。 upsert: false
を指定しなかった場合でも 、これがデフォルト値であるため、falseであることがわかります(つまり、アップサートオプションを指定しない場合に使用される値です)。
コレクションをもう一度見ると、ドキュメントがアップサートされていないことがわかります。
db.pets.find()
結果:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Scratch", "type" : "Cat" }
upsert: true
を使用した例
ここでもここにありますが、今回はupsert: true
を指定します 。
db.pets.findAndModify({
query: { _id: 4 },
update: { _id: 4, name: "Fetch", type: "Dog" },
new: true,
upsert: true
})
結果:
{ "_id" : 4, "name" : "Fetch", "type" : "Dog" }
今回は新しいドキュメントがアップサートされ、アップサートされたドキュメントが出力として表示されます(new: true
を指定したため) 。
コレクションをもう一度確認しましょう。
db.pets.find()
結果:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Scratch", "type" : "Cat" } { "_id" : 4, "name" : "Fetch", "type" : "Dog" }
したがって、新しいドキュメントが実際にアップサートされたことがわかります。
arrayFiltersパラメーター
配列を操作するときは、arrayFilters
を使用できます 位置$
とともにパラメータ 更新する配列要素を決定する演算子。これにより、位置がわからなくても、値に基づいて配列要素を更新できます。
たとえば、players
というコレクションがあるとします。 次のドキュメントを使用:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
次のクエリを実行して、特定の量(この場合は10)よりも高い値を持つ配列要素のみを更新できます。
db.players.findAndModify({
query: { scores: { $gte: 10 } },
update: { $set: { "scores.$[e]" : 10 } },
arrayFilters: [ { "e": { $gte: 10 } } ]
})
結果:
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
予想どおり、2つのドキュメントが基準に一致していても、これは1つのドキュメントのみを更新します。
現在のドキュメントは次のようになっています。
db.players.find()
結果:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 10, 10 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
ドキュメント2では、2つの配列要素が基準に一致したため、これらの要素が更新されました。
詳細情報
db.collection.findAndModify()
メソッドは、writeConcern
などの他のパラメータも受け入れます 、collation
、bypassDocumentValidation
など。
db.collections.findAndModify()
についてはMongoDBのドキュメントを参照してください 詳細については。