これには、実際には「2」(またはupsertの場合は「3」)の更新ステートメントが必要であり、「一括」操作が存在する非常に良い理由の1つです。
db.collection.bulkWrite([
// Attempt to update the matched element
{ "updateOne": {
"filter": {
"name": "SweetTown",
"residents.name": "Bob"
},
"update": {
"$set": { "residents.$.reputation": 30 }
}
},
// $push the element where not matched
{ "updateOne": {
"filter": {
"name": "SweetTown",
"residents.name": { "$ne": "Bob" }
},
"update": {
"$push": {
"residents": { "name": "Bob", "reputation": 30 }
}
}
}}
])
または、実際に"upsert"
を含めたい場合 "SweetTown"
の基本ドキュメント 次に、その懸念を独自のテストに分ける必要があります。
db.collection.bulkWrite([
// Attempt to update the matched element
{ "updateOne": {
"filter": {
"name": "SweetTown",
"residents.name": "Bob"
},
"update": {
"$set": { "residents.$.reputation": 30 }
}
},
// $push the element where not matched
{ "updateOne": {
"filter": {
"name": "SweetTown",
"residents.name": { "$ne": "Bob" }
},
"update": {
"$push": {
"residents": { "name": "Bob", "reputation": 30 }
}
}
}},
// Only use $setOnInsert when actually an upsert
{ "updateOne": {
"filter": {
"name": "SweetTown"
},
"update": {
"$setOnInsert": {
"residents": [{ "name": "Bob", "reputation": 30 }]
}
},
"upsert": true
}}
])
したがって、一般的な概念はのみです。 $setOnInsert
を適用します
"upsert"
の場合のアクション 実際に発生します。これがこの場合にのみ発生することを確認するために、実際に配列要素を調べている他の操作は、"upsert"
でマークされていません。 オプション。その部分は意図的なものです。
どのように見ても、それは1つでのみ可能です。 要素が見つかったかどうか、またはドキュメントが見つからずに新しいドキュメントが作成されたときに、データベースに実際に変更を加えるためのこれらの操作の1つ。
いずれの場合も、単一の更新ステートメントでそのような操作を実行することはできません。ただし、「一括」操作は実際には1つのみであるため 1つでリクエスト 応答後、アプリケーションに関する限り、サーバーと一度通信するだけで済みます。 サーバーにこれら3つのことすべてを試してもらい、応答を返すようにします。
直接バルクAPIの以前の使用法の場合、代替構文は次のとおりです。
var bulk = db.collection.initializeOrderedBulkOp();
// $set matched where existing
bulk.find({ "name": "SweetTown", "residents.name": "Bob" }).updateOne({
"$set": { "residents.$.reputation": 30 }
});
// $push where not existing
bulk.find({ "name": "SweetTown", "residents.name": { "$ne": "Bob" } }).updateOne({
"$push": { "residents": { "name": "Bob", "reputation": 30 } }
});
// Attempt to upsert only
bulk.find({ "name": "SweetTown" }).upsert().updateOne({
"$setOnInsert": {
"residents": [{ "name": "Bob", "reputation": 30 }]
}
})
bulk.execute();