MongoDB memiliki $push
operator dan $addToSet
operator, keduanya melakukan hal yang sangat mirip.
Kedua operator menambahkan nilai ke larik yang ada. Perbedaan utama adalah bagaimana mereka menangani array yang sudah berisi nilai yang Anda coba tambahkan, dan juga di pengubah yang dapat digunakan.
Perbedaan
Nilai yang Ada | Jika nilai sudah ada dalam array, $push masih akan menambahkan nilai (menghasilkan nilai duplikat). Namun, $addToSet hanya menambahkan nilai jika belum ada dalam array. Oleh karena itu, jika nilainya sudah ada, $addToSet tidak akan menambahkannya (tidak akan menghasilkan apa-apa). |
Pengubah | $push operator dapat digunakan dengan pengubah tambahan, seperti $sort , $slice , dan $position , sedangkan $addToSet tidak bisa (setidaknya, tidak pada MongoDB 4.4). |
Nilai yang Ada
Misalkan kita memiliki koleksi dengan dokumen-dokumen berikut:
db.players.find()
Hasil:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 3, 5, 5 ] }
Mari gunakan $addToSet
untuk mencoba menambahkan nilai ke salah satu larik.
db.players.update(
{ _id: 3 },
{ $addToSet: { scores: 5 } }
)
Keluaran:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
Ini memberitahu kita bahwa ada dokumen yang cocok (dokumen 3), tetapi tidak dimodifikasi. Itu tidak diubah karena nilai yang kami coba masukkan (5
) sudah ada dalam larik.
Yuk intip koleksinya:
db.players.find()
Hasil:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 3, 5, 5 ] }
Seperti yang diharapkan, dokumen 3 belum diubah.
Ayo coba $push
sebagai gantinya:
db.players.update(
{ _id: 3 },
{ $push: { scores: 5 } }
)
Keluaran:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Kali ini kami melihat bahwa dokumen tersebut telah dimodifikasi.
Kami dapat memverifikasi ini dengan memeriksa koleksi lagi:
db.products.find()
Hasil:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 3, 5, 5, 5 ] }
Pengubah
$push
operator dapat digunakan dengan pengubah seperti $position
, $sort
, dan $slice
.
$addToSet
operator tidak dapat digunakan dengan pengubah ini.
Inilah yang terjadi jika saya mencoba menggunakan pengubah ini dengan $addToSet
:
db.players.update(
{ _id: 3 },
{
$addToSet: {
scores: {
$each: [ 12 ],
$position: 0,
$sort: 1,
$slice: 5
}
}
}
)
Keluaran:
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 2, "errmsg" : "Found unexpected fields after $each in $addToSet: { $each: [ 12.0 ], $position: 0.0, $sort: 1.0, $slice: 5.0 }" } })
Pesan kesalahan memberitahu kita bahwa $position
, $sort
, dan $slice
adalah bidang yang tidak terduga (yaitu, tidak boleh ada di sana).
Mari kita coba pengubah yang sama dengan $push
:
db.players.update(
{ _id: 3 },
{
$push: {
scores: {
$each: [ 12 ],
$position: 0,
$sort: 1,
$slice: 5
}
}
}
)
Keluaran:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Kali ini berhasil tanpa kesalahan.
Verifikasi hasilnya:
db.players.find()
Hasil:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 3, 5, 5, 5, 12 ] }
Kita dapat melihat bahwa nilai telah ditambahkan. Meskipun kami menetapkan $position: 0
, kami juga menentukan $sort: 1
, yang berarti bahwa array diurutkan setelah kita memposisikannya.
Kami juga menentukan $slice: 5
, yang membatasi larik hanya menjadi 5 elemen (yang ternyata, sebenarnya adalah berapa banyak elemen yang ada di dalam larik).