MongoDBの多くの更新操作は、アップサートになる可能性があります。アップサートは、挿入と更新の組み合わせです。
これは次のように機能します。フィルター基準に基づいて更新操作を実行し、一致するものがある場合は一致するドキュメントのみが更新されますが、一致するものがない場合は新しいドキュメントが挿入されます。
例
pets
というコレクションがあるとします。 次のドキュメントが含まれています:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
upsert
を設定する次の更新操作を実行できます。 true
へのパラメータ :
db.pets.updateOne(
{ name: "Wag" },
{ $set: { type: "Cow" } },
{ upsert: true }
)
結果:
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
この場合、一致するドキュメントがありました(つまり、name: "Wag"
のドキュメントがあります )したがって、一致するドキュメントが更新されました。何も挿入されませんでした。
これは次のように確認できます:
db.pets.find()
結果:
{ "_id" : 1, "name" : "Wag", "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
これで、最初のドキュメントにtype
が追加されました Cow
の 。
もう一度upsert: true
を使用して、別の更新操作を実行してみましょう 。ただし、今回は、更新する一致するドキュメントはありません。
db.pets.updateOne(
{ name: "Bubbles" },
{ $set: { type: "Fish" } },
{ upsert: true }
)
結果:
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0, "upsertedId" : ObjectId("5fe1b4c8d9914101694100b7") }
この例では、name: "Bubbles"
を持つドキュメントを見つけようとします。 しかし、何も見つかりません。
今回は、matchedCount
であることがわかります。 0
です 、およびmodifiedCount
0
でもあります 。これは、既存のドキュメントが更新されていないことを意味します。
upsertedId
が返されました。これは、ドキュメントがアップサートされたことを意味します。
ドキュメントのコレクションをもう一度見てみましょう:
db.pets.find()
結果:
{ "_id" : 1, "name" : "Wag", "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" } { "_id" : ObjectId("5fe1b4c8d9914101694100b7"), "name" : "Bubbles", "type" : "Fish" }
新しいドキュメントが挿入/アップロードされ、上記と同じIDを持っていることがわかります。
今回は更新する一致するドキュメントがなかったため、アップサートが発生しました(したがって、代わりに新しいドキュメントが挿入/アップサートされました)。
upsert: true
を設定していなかった場合 、そのドキュメントは挿入されていなかったでしょう。
一括更新に関するアップサート
一括更新を実行するときに、upsert: true
を指定する場合 、Bulk.find.upsert()
で使用する必要があります 。
これは、次の書き込み操作で使用できます。
-
Bulk.find.replaceOne()
-
Bulk.find.updateOne()
-
Bulk.find.update()
構文は次のようになります:
Bulk.find(<query>).upsert().update(<update>);
Bulk.find(<query>).upsert().updateOne(<update>);
Bulk.find(<query>).upsert().replaceOne(<replacement>);
例:
var bulk = db.pets.initializeUnorderedBulkOp();
bulk.find( { name: "Bruce" } ).upsert().replaceOne(
{
name: "Bruce",
type: "Bat",
}
);
bulk.execute();
結果:
BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 0, "nUpserted" : 1, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ { "index" : 0, "_id" : ObjectId("5fe1c179d9914101694100dd") } ] })
1つのドキュメントがアップサートされたことがわかります。 _id
も表示されます そのドキュメント用に生成されました。
これで、コレクション内のドキュメントを表示すると、アップサートされた新しいドキュメントを確認できます。
db.pets.find()
結果:
{ "_id" : 1, "name" : "Wag", "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" } { "_id" : ObjectId("5fe1b4c8d9914101694100b7"), "name" : "Bubbles", "type" : "Fish" } { "_id" : ObjectId("5fe1c179d9914101694100dd"), "name" : "Bruce", "type" : "Bat" }