Proses di sini sangat sederhana, hanya bervariasi di mana Anda ingin "menemukan atau membuat" elemen dalam array.
Pertama, dengan asumsi elemen untuk setiap kunci sudah ada, maka kasus sederhananya adalah menanyakan elemen dan memperbarui dengan indeks yang dikembalikan melalui posisi $
operator:
db.collection.update(
{
"_id": docId,
"attrs": { "$elemMatch": { "key": "A1", "type": "T1" } }
}
{ "$set": { "attrs.$.value": "20" }
)
Itu hanya akan mengubah elemen yang cocok tanpa mempengaruhi yang lain.
Dalam kasus kedua di mana "temukan atau buat" diperlukan dan kunci tertentu mungkin tidak ada, maka Anda menggunakan pernyataan pembaruan "dua". Tetapi API Operasi Massal memungkinkan Anda melakukan ini dalam satu permintaan ke server dengan satu respons:
var bulk = db.collection.initializeOrderedBulkOp();
// Try to update where exists
bulk.find({
"_id": docId,
"attrs": { "$elemMatch": { "key": "A1", "type": "T2" } }
}).updateOne({
"$set": { "attrs.$.value": "30" }
});
// Try to add where does noes not exist
bulk.find({
"_id": docId,
"attrs": { "$not": { "$elemMatch": { "key": "A1", "type": "T2" } } }
}).updateOne({
"$push": { "attrs": { "key": "A1", "type": "T2", "value": "30" } }
});
bulk.execute();
Logika dasarnya adalah bahwa upaya pembaruan pertama dilakukan untuk mencocokkan elemen dengan nilai yang diperlukan seperti yang dilakukan sebelumnya. Kondisi lain menguji di mana elemen tidak ditemukan sama sekali dengan membalikkan logika kecocokan dengan $not
.
Dalam kasus di mana elemen array tidak ditemukan maka yang baru valid untuk penambahan melalui $push
.
Saya benar-benar harus menambahkan bahwa karena kami secara khusus mencari kecocokan negatif di sini, selalu merupakan ide yang baik untuk mencocokkan "dokumen" yang ingin Anda perbarui dengan beberapa pengenal unik seperti _id
kunci. Meskipun memungkinkan dengan pembaruan "multi", Anda harus berhati-hati dengan apa yang Anda lakukan.
Jadi dalam hal menjalankan proses "temukan atau buat" maka elemen yang tidak cocok ditambahkan ke array dengan benar, tanpa mengganggu elemen lain, juga pembaruan sebelumnya untuk kecocokan yang diharapkan diterapkan dengan cara yang sama:
{
"_id" : ObjectId("55b570f339db998cde23369d"),
"attrs" : [
{
"key" : "A1",
"type" : "T1",
"value" : "20"
},
{
"key" : "A2",
"type" : "T2",
"value" : "14"
},
{
"key" : "A1",
"type" : "T2",
"value" : "30"
}
]
}
Ini adalah pola sederhana untuk diikuti, dan tentu saja Operasi Massal di sini menghapus semua overhead yang terlibat dengan mengirim dan menerima beberapa permintaan ke dan dari server. Semua ini dengan senang hati bekerja tanpa mengganggu elemen lain yang mungkin ada atau tidak ada.
Selain itu, ada manfaat tambahan dari menyimpan data dalam array untuk kueri dan analisis yang mudah karena didukung oleh operator standar tanpa perlu kembali ke pemrosesan server JavaScript untuk melintasi elemen.