updateOne, updateMany — $set, $unset, $inc, $push, $pull
Muammodan boshlaylik
Foydalanuvchi parolini o'zgartirdi — faqat parol maydonini yangilash kerak.
Mahsulot soni kamaydi — soni ni 1 ga kamaytirish kerak.
Foydalanuvchi yangi hobby qo'shdi — hobbylar massiviga element qo'shish kerak.
Bularning barchasi uchun MongoDB da update operatorlari bor.
$set, $unset, $inc, $push, $pull — har biri o'z vazifasiga ega.
update — asosiy tuzilish
db.<collection>.updateOne(<filter>, <update>, <options>)
↑ ↑
Qaysinisi Nima qilish
Update ikki qismdan iborat:
- Filter — qaysi documentni yangilash (8-darsda o'rgandik)
- Update — nima o'zgartirilsin (bu darsning asosi)
updateOne vs updateMany
updateOne → filtrdagi BIRINCHI documentni yangilaydi
updateMany → filtrdagi BARCHA documentlarni yangilaydi
// Bitta — Jasur degan birinchi foydalanuvchi
db.users.updateOne(
{ ism: "Jasur" },
{ $set: { faol: false } }
)
// Ko'p — barcha Toshkentliklar
db.users.updateMany(
{ shahar: "Toshkent" },
{ $set: { viloyat: "Toshkent shahri" } }
)
SQL bilan:
-- SQL — WHERE bo'lmasa hammasi o'zgaradi (xavfli!)
UPDATE users SET faol = false WHERE ism = 'Jasur' LIMIT 1;
UPDATE users SET viloyat = 'Toshkent shahri' WHERE shahar = 'Toshkent';
Qaytarilgan natija
let natija = db.users.updateOne(
{ ism: "Jasur" },
{ $set: { faol: false } }
)
natija:
{
acknowledged: true,
matchedCount: 1, ← filtriga mos keldi
modifiedCount: 1, ← haqiqatan o'zgartirildi
upsertedId: null ← upsert bo'lmadi (10-darsda)
}
matchedCount vs modifiedCount:
matchedCount: 1 } Bir xil bo'lishi mumkin
modifiedCount: 1 }
Lekin:
matchedCount: 1 } Topildi, lekin qiymat allaqachon bir xil edi
modifiedCount: 0 } — o'zgartirilmadi
$set — maydon qiymatini o'rnatish
Eng ko'p ishlatiladigan operator. Mavjud maydonni yangilaydi yoki yangi maydon qo'shadi.
// Mavjud maydonni yangilash
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $set: { yosh: 25 } } // yosh: 24 → yosh: 25
)
// Yangi maydon qo'shish
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $set: { sinf: "11A" } } // sinf maydoni yo'q edi → qo'shildi
)
// Bir nechta maydon bir vaqtda
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $set: { yosh: 25, sinf: "11A", shahar: "Andijon" } }
)
OLDIN: { ism: "Jasur", yosh: 24, shahar: "Toshkent" }
↓ $set: { yosh: 25, sinf: "11A" }
KEYIN: { ism: "Jasur", yosh: 25, shahar: "Toshkent", sinf: "11A" }
↑ ↑
yangilandi qo'shildi
Ichki maydonni $set bilan yangilash
// manzil.shahar ni yangilash — butun manzil emas, faqat shahar
db.users.updateOne(
{ ism: "Jasur" },
{ $set: { "manzil.shahar": "Andijon" } } // ← dot notation
)
// ❌ Bu butun manzil ob'ektini almashtiradi
db.users.updateOne(
{ ism: "Jasur" },
{ $set: { manzil: { shahar: "Andijon" } } }
// tuman, ko'cha — yo'qoladi!
)
$unset — maydonni o'chirish
// sinf maydonini o'chirish
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $unset: { sinf: "" } } // qiymat ahamiyatsiz — "" yoki 1 yoki true
)
OLDIN: { ism: "Jasur", yosh: 25, sinf: "11A" }
↓ $unset: { sinf: "" }
KEYIN: { ism: "Jasur", yosh: 25 }
sinf yo'q bo'ldi
// Bir nechta maydonni birga o'chirish
db.users.updateOne(
{ ism: "Jasur" },
{ $unset: { vaqtinchalik_kod: "", muddati: "" } }
)
SQL bilan (to'g'ridan-to'g'ri analog yo'q, NULL qo'yamiz):
-- SQL
UPDATE users SET sinf = NULL WHERE ism = 'Jasur';
-- SQL da ustunni o'chira olmaymiz, NULL qilamiz
// MongoDB da maydon butunlay yo'qoladi — NULL ham qolmaydi
db.users.updateOne({ ism: "Jasur" }, { $unset: { sinf: "" } })
$inc — raqamni oshirish yoki kamaytirish
// Yoshni 1 ga oshirish
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $inc: { yosh: 1 } } // yosh = yosh + 1
)
// Ko'rishlar sonini 1 ga oshirish (view counter)
db.postlar.updateOne(
{ _id: postId },
{ $inc: { korishlar: 1 } }
)
// Balansdan 5000 ayirish
db.hisoblar.updateOne(
{ foydalanuvchi_id: userId },
{ $inc: { balans: -5000 } } // manfiy qiymat — kamaytiradi
)
// Bir nechta maydon bir vaqtda
db.o_yinlar.updateOne(
{ o_yinchi_id: id },
{ $inc: { ball: 10, darajalar: 1 } }
)
OLDIN: { ism: "Jasur", yosh: 24, korishlar: 142 }
↓ $inc: { yosh: 1, korishlar: 1 }
KEYIN: { ism: "Jasur", yosh: 25, korishlar: 143 }
SQL bilan:
UPDATE postlar SET korishlar = korishlar + 1 WHERE id = ?;
// MongoDB
db.postlar.updateOne({ _id: id }, { $inc: { korishlar: 1 } })
$inc — $set: { korishlar: 143 } dan yaxshiroq, chunki $inc atomik.
Ikki server bir vaqtda korishlar ni o'qib, ikkalasi ham 143 yozsa —
bir oshirish yo'qoladi. $inc esa MongoDB serverida atomik bajariladi.
$push — massivga element qo'shish
// Hobby qo'shish
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $push: { hobbylar: "shaxmat" } }
)
OLDIN: { hobbylar: ["dasturlash", "futbol"] }
↓ $push: { hobbylar: "shaxmat" }
KEYIN: { hobbylar: ["dasturlash", "futbol", "shaxmat"] }
↑ qo'shildi
$push — bir nechta element
// $each bilan bir nechta qo'shish
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $push: { hobbylar: { $each: ["kitob", "musiqa"] } } }
)
$push + $sort + $slice — tartiblab, soni cheklang
// So'nggi 5 ta xabarni saqlash (eski o'chib ketadi)
db.users.updateOne(
{ _id: userId },
{
$push: {
bildirishnomalar: {
$each: [{ matn: "Yangi xabar", vaqt: new Date() }],
$sort: { vaqt: -1 }, // yangilarni boshiga
$slice: 5 // faqat 5 tasini saqlaydi
}
}
}
)
Oldin: [B5, B4, B3, B2, B1] (5 ta bor)
Yangi: B6 qo'shildi
[B6, B5, B4, B3, B2, B1] → sort + slice(5) →
Keyin: [B6, B5, B4, B3, B2] (B1 tushib ketdi)
$addToSet — massivga faqat unikal qo'shish
// Agar "dasturlash" allaqachon bor bo'lsa — qo'shilmaydi
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $addToSet: { hobbylar: "dasturlash" } }
)
$push vs $addToSet:
hobbylar: ["dasturlash", "futbol"]
$push: → ["dasturlash", "futbol", "dasturlash"] ← dublikat!
$addToSet: → ["dasturlash", "futbol"] ← o'zgarmadi
Teglar, kategoriyalar, rollar kabi unikal bo'lishi kerak bo'lgan
massivlarda $addToSet ishlatiladi.
$pull — massivdan element o'chirish
// "futbol" hobby ni o'chirish
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $pull: { hobbylar: "futbol" } }
)
OLDIN: { hobbylar: ["dasturlash", "futbol", "shaxmat"] }
↓ $pull: { hobbylar: "futbol" }
KEYIN: { hobbylar: ["dasturlash", "shaxmat"] }
$pull — shart bilan o'chirish
// Bahosi 60 dan past bo'lgan baholarni o'chirish
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $pull: { baholar: { $lt: 60 } } }
)
// Ob'ekt massividan shart bilan o'chirish
db.users.updateOne(
{ _id: userId },
{ $pull: { manzillar: { shahar: "Toshkent" } } }
)
$pop — massivdan boshidan yoki oxiridan o'chirish
// Oxirgi elementni o'chirish
db.users.updateOne({ _id: id }, { $pop: { telefon: 1 } })
// Birinchi elementni o'chirish
db.users.updateOne({ _id: id }, { $pop: { telefon: -1 } })
$rename — maydon nomini o'zgartirish
// "ism" ni "name" ga o'zgartirish
db.users.updateMany(
{},
{ $rename: { "ism": "name" } }
)
Migration paytida foydali — eski nomdan yangisiga o'tish.
updateMany — barcha documentlarni yangilash
// Barcha talabalarning "yil" maydonini qo'shish
db.talabalar.updateMany(
{}, // ← barcha documentlar
{ $set: { yil: 2024 } }
)
// Faqat 10-sinf talabalariga sinf_raqam qo'shish
db.talabalar.updateMany(
{ sinf: /^10/ }, // sinfi "10" bilan boshlanadi
{ $set: { sinf_raqam: 10 } }
)
// Barcha mahsulot narxini 10% oshirish
db.mahsulotlar.updateMany(
{ faol: true },
{ $mul: { narx: 1.10 } } // $mul — ko'paytirish
)
SQL bilan:
UPDATE talabalar SET yil = 2024;
UPDATE mahsulotlar SET narx = narx * 1.10 WHERE faol = TRUE;
$mul — ko'paytirish
// Narxni 1.1 ga ko'paytirish (10% qimmatlashtirish)
db.mahsulotlar.updateMany(
{},
{ $mul: { narx: 1.10 } }
)
// Narxni 0.9 ga ko'paytirish (10% chegirma)
db.mahsulotlar.updateMany(
{ chegirma: true },
{ $mul: { narx: 0.90 } }
)
Bir nechta operator birgalikda
Bir update ichida bir nechta operatorni birlashtirish mumkin:
db.users.updateOne(
{ _id: userId },
{
$set: { so_nggi_kirish: new Date(), faol: true },
$inc: { kirish_soni: 1 },
$unset: { vaqtinchalik_token: "" }
}
)
Bajarilishi:
1. so'nggi_kirish = hozirgi vaqt
2. faol = true
3. kirish_soni = kirish_soni + 1
4. vaqtinchalik_token o'chdi
— hammasi bitta atomik operatsiyada!
Ehtiyot bo'lish kerak bo'lgan holat
Operator yo'q = documentni to'liq almashtirish
// ❌ XAVFLI — document to'liq almashadi!
db.talabalar.updateOne(
{ ism: "Jasur" },
{ yosh: 25 } // ← $set yo'q!
)
OLDIN: { _id: ..., ism: "Jasur", yosh: 24, shahar: "Toshkent", sinf: "11A" }
↓ { yosh: 25 }
KEYIN: { _id: ..., yosh: 25 }
ism, shahar, sinf — yo'qoldi!
Sabab: operator ($set, $inc va h.k.) yo'q bo'lsa, MongoDB
documentni filter bilan topib, to'liq berilgan ob'ekt bilan
almashtiradi. _id saqlanadi, qolgan hammasi o'zgaradi.
// ✅ To'g'ri — $set bilan faqat yosh o'zgaradi
db.talabalar.updateOne(
{ ism: "Jasur" },
{ $set: { yosh: 25 } }
)
Bu eng ko'p uchraydigan xato — doim $set va boshqa operatorlarni
ishlating.
Tez-tez uchraydigan xatolar
updateMany ga filter bermaslik
// ❌ Juda xavfli — barcha documentlar o'zgaradi
db.users.updateMany({}, { $set: { faol: false } })
// ↑ bo'sh filter — hammasi
// ✅ Oldin find bilan tekshiring
db.users.find({ faol: true }).count() // nechta o'zgarishi
db.users.updateMany({ faol: true }, { $set: { faol: false } })
$push bilan dublikat muammo
// Har marta bosilganda hobby qo'shilib boradi
db.users.updateOne({ _id: id }, { $push: { hobbylar: "futbol" } })
// ["futbol", "futbol", "futbol", ...]
// ✅ $addToSet ishlatish
db.users.updateOne({ _id: id }, { $addToSet: { hobbylar: "futbol" } })
$inc mavjud bo'lmagan maydonni oshirish
// korishlar maydoni yo'q document
db.postlar.updateOne(
{ _id: id },
{ $inc: { korishlar: 1 } }
)
// Xato emas! MongoDB korishlar: 0 dan boshlaydi → 1 bo'ladi
// $inc maydon bo'lmasa, 0 dan boshlab oshiradi
Bu aslida foydali xususiyat — counter larni boshlang'ich qiymat belgilamasdan ishlatish mumkin.
Xulosa
┌─────────────────────────────────────────────────────────────┐
│ $set { $set: { a: 1 } } maydon qo'sh/yangilash │
│ $unset { $unset: { a: "" } } maydonni o'chirish │
│ $inc { $inc: { n: 1 } } raqamni oshir/kamayti │
│ $mul { $mul: { n: 1.1 } } raqamni ko'paytir │
│ $rename{ $rename: {a: "b"} } nom o'zgartir │
├─────────────────────────────────────────────────────────────┤
│ $push massivga qo'shish (dublikat mumkin) │
│ $addToSet massivga faqat unikal qo'shish │
│ $pull massivdan o'chirish (shart bilan ham) │
│ $pop massivdan boshi/oxiridan o'chirish │
└─────────────────────────────────────────────────────────────┘
- Operatorsiz
update→ document to'liq almashadi — eng xavfli xato $incatomik — counter larda doim shu$addToSetvs$push— unikal kerakmi, yo'qmiupdateMany({}, ...)— filtrsiz barcha document o'zgaradi, ehtiyot bo'ling
Keyingi dars: 10-dars — upsert, findOneAndUpdate, findOneAndDelete