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