MongoDB Academy · Pelajaran

Operator Kemas Kini Tatasusunan: $push, $pull, $addToSet

Pelajar akan menambah dan membuang item daripada tatasusunan dalam dokumen menggunakan operator kemas kini tatasusunan yang disasarkan.

Pelajaran 3 daripada 413 langkah

Operator Kemas Kini Tatasusunan: $push, $pull, $addToSet ialah pelajaran MongoDB Academy percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran MongoDB Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus MongoDB Academy merangkumi sejumlah 4 pelajaran.

Tatasusunan sebagai Komponen Utama

Tatasusunan dalam dokumen MongoDB adalah perkara biasa—produk mempunyai tags, pengguna mempunyai roles dan pesanan mempunyai items. Apabila tatasusunan ini perlu berubah (menambah tag, membuang peranan atau menambah item pesanan), anda memerlukan operator kemas kini tatasusunan yang mengubah tatasusunan terus tanpa menggantikan keseluruhan dokumen.

MongoDB menyediakan set operator yang lengkap untuk tujuan ini: $push menambah elemen, $pull membuang elemen berdasarkan nilai, $pop membuang elemen dari hujung, dan $addToSet menambah elemen hanya jika nilainya unik. Kesemuanya atomik—perubahan berlaku dalam satu operasi pada pelayan.

$push: Menambah Elemen pada Tatasusunan

Operator $push menambahkan satu atau lebih elemen pada medan tatasusunan. Jika medan itu tidak wujud, $push menciptanya sebagai tatasusunan baharu yang mengandungi elemen yang ditambah. Jika medan itu wujud tetapi bukan tatasusunan, operasi akan gagal.

Satu $push dengan nilai biasa menambah satu elemen. Untuk menambah beberapa elemen dalam satu operasi, gabungkan $push dengan pengubah $each. $push tidak menyemak pendua—gunakan $addToSet jika anda memerlukan nilai unik.

// Push a single element
db.posts.updateOne(
  { _id: postId },
  { $push: { tags: 'mongodb' } }
);
// tags: ['node', 'backend'] -> ['node', 'backend', 'mongodb']

// Push multiple elements using $each
db.posts.updateOne(
  { _id: postId },
  { $push: { tags: { $each: ['databases', 'nosql'] } } }
);
// tags: ['node'] -> ['node', 'databases', 'nosql']

// Push a sub-document
db.users.updateOne(
  { _id: userId },
  { $push: { addresses: { street: '123 Main St', city: 'Chicago' } } }
);

$push Dengan $sort dan $slice

Menggabungkan $push dengan pengubah $sort dan $slice menghasilkan tatasusunan tersusun berhad: tambah elemen baharu, susun tatasusunan, kemudian hadkannya kepada panjang maksimum. Corak ini sesuai untuk mengekalkan senarai 'N teratas' atau log 'N item terkini'.

Pengubah $slice mengehadkan tatasusunan kepada N elemen pertama selepas penyusunan. Gunakan nilai negatif untuk N elemen terakhir (contohnya, $slice: -5 mengekalkan 5 elemen terakhir selepas penyusunan). Gabungan ini memerlukan $each walaupun anda hanya menambah satu item.

// Maintain a 'top 5 scores' list
db.players.updateOne(
  { _id: playerId },
  {
    $push: {
      topScores: {
        $each:  [{ score: 9800, date: new Date() }],
        $sort:  { score: -1 },  // Sort by score descending
        $slice: 5               // Keep only top 5
      }
    }
  }
);
// After: topScores always has max 5 entries, highest scores first

$pull: Membuang Elemen Berdasarkan Nilai

Operator $pull membuang semua elemen daripada tatasusunan yang sepadan dengan nilai atau syarat tertentu. Tidak seperti $pop (yang membuang elemen dari hujung), $pull membuang elemen berdasarkan nilainya, di mana-mana sahaja dalam tatasusunan.

Anda boleh memberikan nilai mudah (untuk tatasusunan primitif) atau syarat pertanyaan (untuk tatasusunan subdokumen). $pull membuang semua elemen yang sepadan dalam satu operasi atomik—anda tidak perlu mengetahui kedudukan elemen tersebut.

// Remove a tag by value
db.posts.updateOne(
  { _id: postId },
  { $pull: { tags: 'outdated' } }
);
// tags: ['mongodb', 'outdated', 'nosql'] -> ['mongodb', 'nosql']
// Removes ALL occurrences of 'outdated'

// Pull with a condition on array of sub-documents
db.orders.updateOne(
  { _id: orderId },
  { $pull: { items: { sku: 'REMOVED-ITEM' } } }
);
// Removes all items where sku = 'REMOVED-ITEM' from the items array

$pop: Membuang Elemen dari Hujung Tatasusunan

Operator $pop membuang elemen pertama atau terakhir daripada tatasusunan tanpa perlu mengetahui nilainya. Gunakan $pop: { field: 1 } untuk membuang elemen terakhir, dan $pop: { field: -1 } untuk membuang elemen pertama.

$pop berguna untuk melaksanakan baris gilir dan deq: tambah ke belakang dengan $push, kemudian keluarkan dari hadapan dengan $pop: -1. Walau bagaimanapun, untuk sistem baris gilir produksi, pertimbangkan penyelesaian khusus—baris gilir berasaskan dokumen mempunyai batasan apabila keserentakan tinggi.

// Remove the last element
db.playlists.updateOne(
  { _id: playlistId },
  { $pop: { songs: 1 } }   // 1 = last
);
// songs: ['A', 'B', 'C'] -> ['A', 'B']

// Remove the first element
db.queues.updateOne(
  { _id: queueId },
  { $pop: { items: -1 } }  // -1 = first
);
// items: ['task1', 'task2', 'task3'] -> ['task2', 'task3']

$addToSet: Penyisipan Elemen Unik

Operator $addToSet menambah elemen pada tatasusunan hanya jika elemen itu belum wujud. Jika elemen itu sudah wujud, operasi tidak melakukan apa-apa—tiada pendua ditambah. Ini sesuai untuk mengekalkan set nilai unik seperti tag, peranan pengguna atau keahlian kategori.

Seperti $push, $addToSet menyokong pengubah $each untuk menambah beberapa elemen unik dalam satu operasi. Jika medan itu tidak wujud, pengubah ini mencipta tatasusunan tersebut. Jenis dan nilai BSON mesti sepadan tepat untuk semakan pendua.

// Add tag only if not already present
db.posts.updateOne(
  { _id: postId },
  { $addToSet: { tags: 'mongodb' } }
);
// If tags already has 'mongodb': no change
// If not: 'mongodb' is added

// Add multiple unique roles with $each
db.users.updateOne(
  { _id: userId },
  { $addToSet: { roles: { $each: ['viewer', 'commenter'] } } }
);
// Only adds roles that aren't already in the array
// 'viewer' already exists? Skipped. 'commenter' new? Added.

$push berbanding $addToSet: Membuat Pilihan

Pilihan antara $push dan $addToSet bergantung pada sama ada susunan dan pendua boleh diterima:

  • Gunakan $push apabila: susunan penting, pendua boleh diterima (atau dijangka), anda memerlukan tatasusunan tersusun dengan $sort/$slice, atau anda sedang membina log/sejarah yang mengandungi nilai berulang secara munasabah
  • Gunakan $addToSet apabila: anda mengurus set nilai unik (peranan, keizinan, tag, langganan) dan penambahan nilai yang sedia ada sepatutnya tidak melakukan apa-apa

Perlu diingat bahawa $addToSet mesti mengimbas tatasusunan sedia ada untuk menyemak pendua—bagi tatasusunan yang sangat besar (ribuan elemen), proses ini boleh menjadi perlahan. Pertimbangkan koleksi berasingan untuk set unik yang besar.

// $push for ordered history (duplicates ok)
db.users.updateOne(
  { _id: userId },
  { $push: { loginHistory: { at: new Date(), ip: req.ip } } }
);
// Same IP can appear multiple times - that's fine for history

// $addToSet for unique roles (no duplicates)
db.users.updateOne(
  { _id: userId },
  { $addToSet: { roles: 'editor' } }
);
// 'editor' is either added or already there - always unique

Membuang Elemen Tertentu daripada Tatasusunan Bersarang

Apabila dokumen anda mempunyai tatasusunan subdokumen dan anda perlu membuang subdokumen tertentu berdasarkan salah satu medannya, gunakan $pull dengan ungkapan syarat. Syarat itu dinilai terhadap setiap elemen tatasusunan dan semua elemen yang sepadan akan dibuang.

Untuk membuang beberapa nilai tertentu serentak daripada tatasusunan primitif, $pullAll ialah jalan pintas yang menerima tatasusunan nilai untuk dibuang: { $pullAll: { tags: ['oldTag1', 'oldTag2'] } }. Ia setara dengan { $pull: { tags: { $in: ['oldTag1', 'oldTag2'] } } }.

// Remove all items in an order for a discontinued product
db.carts.updateOne(
  { _id: cartId },
  {
    $pull: {
      items: { productId: ObjectId('discontinued-id') }
    }
  }
);

// $pullAll: remove multiple values at once
db.posts.updateOne(
  { _id: postId },
  { $pullAll: { tags: ['spam', 'outdated', 'test'] } }
);
// Removes all occurrences of 'spam', 'outdated', and 'test'

Pengurusan Panjang Tatasusunan

Berhati-hati terhadap pertumbuhan tatasusunan tanpa had. Tatasusunan yang terus membesar (tatasusunan tanpa had) menyebabkan dokumen melebihi had 16 MB MongoDB dan menurunkan prestasi apabila saiz indeks tatasusunan meningkat.

Strategi untuk tatasusunan berhad:

  • Gunakan $push + $slice: -N untuk mengekalkan hanya N elemen terakhir (tetingkap bergulir)
  • Tetapkan peraturan perniagaan: maksimum 50 item dalam troli, maksimum 100 entri sejarah
  • Untuk koleksi yang benar-benar tidak terhad, pindahkan data ke koleksi berasingan dengan rujukan dan bukannya membenamkannya
// Keep only the last 100 login history entries
db.users.updateOne(
  { _id: userId },
  {
    $push: {
      loginHistory: {
        $each: [{ at: new Date(), ip: req.ip }],
        $slice: -100   // Keep last 100 (most recent)
      }
    }
  }
);
// loginHistory never exceeds 100 entries
// Oldest entries are automatically dropped

Dunia Sebenar: Sistem Mengikuti Pengguna

Ciri sosial seperti 'ikuti pengguna' dan 'berhenti mengikuti pengguna' dipadankan secara semula jadi dengan $addToSet dan $pull. Apabila seorang pengguna mengikuti seseorang, tambahkan ID pengguna yang diikuti itu pada tatasusunan following milik pengikut. Apabila mereka berhenti mengikuti, keluarkan ID tersebut. Sifat atomik operator ini bermakna dua tindakan ikut/berhenti ikut yang berlaku serentak pada dokumen yang sama akan disiri dengan betul.

Untuk graf sosial yang besar (jutaan pengikut), pendekatan tatasusunan terbenam ini akan mencapai had dokumen 16 MB. Pada skala besar, pindahkan hubungan tersebut ke koleksi follows khusus dengan medan followerId dan followeeId.

// Follow a user
async function followUser(followerId, followeeId) {
  await db.collection('users').updateOne(
    { _id: new ObjectId(followerId) },
    { $addToSet: { following: new ObjectId(followeeId) } }
  );
  // Optionally: add to followee's followers array too
}

// Unfollow a user
async function unfollowUser(followerId, followeeId) {
  await db.collection('users').updateOne(
    { _id: new ObjectId(followerId) },
    { $pull: { following: new ObjectId(followeeId) } }
  );
}

Operator Posisi $ dalam Kemas Kini

Apabila anda perlu mengemas kini elemen tertentu dalam tatasusunan yang sepadan dengan pertanyaan anda, gunakan operator $ posisi. Dalam dokumen kemas kini, $ merujuk kepada elemen tatasusunan pertama yang sepadan dengan syarat penapis.

Contohnya, untuk menandakan item pesanan tertentu sebagai dihantar, tapis menggunakan { 'items.sku': 'A1' }, kemudian kemas kini dengan { : { 'items.$.shipped': true } }. $ bertindak sebagai ruang letak bagi indeks elemen tatasusunan yang sepadan. Jika beberapa elemen sepadan, hanya elemen pertama yang dikemas kini.

// Update a specific array element using positional operator
// Find order containing item sku 'A1', mark it shipped
db.orders.updateOne(
  { _id: orderId, 'items.sku': 'A1' },   // Filter: includes array condition
  { : { 'items.$.shipped': true } }  // $: matched array element index
);
// Before: items: [{sku:'A1',shipped:false},{sku:'B2',shipped:false}]
// After:  items: [{sku:'A1',shipped:true},{sku:'B2',shipped:false}]

Semakan Pantas

Uji pemahaman anda tentang konsep MongoDB & pangkalan data NoSQL daripada pelajaran ini.

Ulang Kaji Pelajaran

Dalam pelajaran ini, anda telah mempelajari bahawa: $push menambahkan elemen pada tatasusunan dan menyokong pengubah $each/$sort/$slice untuk mengekalkan tatasusunan tersusun berhad seperti senarai N teratas; $pull membuang semua elemen yang sepadan berdasarkan nilai atau syarat—gunakan $pullAll untuk membuang beberapa nilai tertentu serentak; dan $addToSet menambah elemen hanya jika elemen itu belum wujud—sesuai untuk mengekalkan set unik seperti peranan pengguna, tag dan keizinan tanpa semakan pendua pada peringkat aplikasi. Seterusnya, kita akan meneroka cara memadam dokumen dengan selamat menggunakan deleteOne dan deleteMany.

Percuma untuk bermula

Pelajari JavaScript dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
30
Pelajaran
120

Soalan Lazim

Adakah pelajaran “Operator Kemas Kini Tatasusunan: $push, $pull, $addToSet” percuma?

Ya — teks penuh “Operator Kemas Kini Tatasusunan: $push, $pull, $addToSet” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus MongoDB Academy, tingkat taraf kepada CoddyKit PRO. Kursus MongoDB Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Operator Kemas Kini Tatasusunan: $push, $pull, $addToSet”?

Pelajar akan menambah dan membuang item daripada tatasusunan dalam dokumen menggunakan operator kemas kini tatasusunan yang disasarkan. Anda berlatih MongoDB Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan MongoDB Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran MongoDB Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “Operator Kemas Kini Tatasusunan: $push, $pull, $addToSet” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran MongoDB Academy ini?

Ya. Setiap pelajaran MongoDB Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. updateOne dan updateMany dengan $set serta $unset
  2. Operator Tambah, Darab dan Min/Maks
  3. Operator Kemas Kini Tatasusunan: $push, $pull, $addToSet
  4. Memadam Dokumen dengan Selamat menggunakan deleteOne dan deleteMany
← Kembali ke MongoDB Academy