Tidak, sebenarnya tidak ada solusi yang lebih baik untuk ini, jadi mungkin dengan penjelasan.
Misalkan Anda memiliki dokumen di tempat yang memiliki struktur seperti yang Anda tunjukkan:
{
"name": "foo",
"bars": [{
"name": "qux",
"somefield": 1
}]
}
Jika Anda melakukan pembaruan seperti ini
db.foo.update(
{ "name": "foo", "bars.name": "qux" },
{ "$set": { "bars.$.somefield": 2 } },
{ "upsert": true }
)
Maka semuanya baik-baik saja karena dokumen yang cocok ditemukan. Tetapi jika Anda mengubah nilai "bars.name":
db.foo.update(
{ "name": "foo", "bars.name": "xyz" },
{ "$set": { "bars.$.somefield": 2 } },
{ "upsert": true }
)
Maka Anda akan mendapatkan kegagalan. Satu-satunya hal yang benar-benar berubah di sini adalah bahwa di MongoDB 2.6 dan di atasnya kesalahannya sedikit lebih ringkas:
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 16836,
"errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: bars.$.somefield"
}
})
Itu lebih baik dalam beberapa hal, tetapi Anda benar-benar tidak ingin "mengganggu". Yang ingin Anda lakukan adalah menambahkan elemen ke larik di mana "nama" saat ini tidak ada.
Jadi yang sebenarnya Anda inginkan adalah "hasil" dari upaya pembaruan tanpa tanda "upsert" untuk melihat apakah ada dokumen yang terpengaruh:
db.foo.update(
{ "name": "foo", "bars.name": "xyz" },
{ "$set": { "bars.$.somefield": 2 } }
)
Mengalah sebagai tanggapan:
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
Jadi ketika dokumen yang dimodifikasi adalah 0
maka Anda tahu Anda ingin mengeluarkan pembaruan berikut:
db.foo.update(
{ "name": "foo" },
{ "$push": { "bars": {
"name": "xyz",
"somefield": 2
}}
)
Benar-benar tidak ada cara lain untuk melakukan apa yang Anda inginkan. Karena penambahan pada larik tidak sepenuhnya merupakan jenis operasi "set", Anda tidak dapat menggunakan $addToSet
digabungkan dengan fungsi "pembaruan massal" di sana, sehingga Anda dapat "mengurutkan" permintaan pembaruan Anda.
Dalam hal ini sepertinya Anda perlu memeriksa hasilnya, atau menerima membaca seluruh dokumen dan memeriksa apakah akan memperbarui atau menyisipkan elemen array baru dalam kode.