MongoDB hujjat yangilash: updateOne va $set
Mahsulot narxi o’zgardi, buyurtma holati “yuborildi” ga o’tdi, omborda soni kamaydi. Bularning har biri mavjud hujjatni o’zgartirishni talab qiladi.
MongoDB’da yangilashning o’z qoidasi bor va u birinchi marta adashtiradi: hujjatni butunlay almashtirish va bir maydonini o’zgartirish ikki xil yozuv.
Misollar uchun baza:
use shop
db.products.drop()
db.products.insertMany([
{ name: "O'tkan kunlar", category: "kitob", price: 45000, quantity: 12 },
{ name: "Mehrobdan chayon", category: "kitob", price: 38000, quantity: 7 },
{ name: "Shum bola", category: "kitob", price: 29000, quantity: 0 },
{ name: "Daftar", category: "kanselyariya", price: 8000, quantity: 150 },
{ name: "Ruchka", category: "kanselyariya", price: 4000, quantity: 300 }
])
{
acknowledged: true,
insertedIds: {
'0': ObjectId('671f8a1b2c3d4e5f6a7b8c31'),
'1': ObjectId('671f8a1b2c3d4e5f6a7b8c32'),
'2': ObjectId('671f8a1b2c3d4e5f6a7b8c33'),
'3': ObjectId('671f8a1b2c3d4e5f6a7b8c34'),
'4': ObjectId('671f8a1b2c3d4e5f6a7b8c35')
}
}
updateOne va $set
Yangilash ikki qismdan iborat: filtr (kimni) va o’zgarish (nima qilish).
db.products.updateOne(
{ name: "Daftar" },
{ $set: { price: 9500 } }
)
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
Natijani tekshiramiz:
db.products.findOne({ name: "Daftar" }, { name: 1, price: 1, _id: 0 })
{ name: 'Daftar', price: 9500 }
Bir vaqtda bir necha maydon:
db.products.updateOne(
{ name: "Ruchka" },
{ $set: { price: 4500, quantity: 280, updatedAt: new Date() } }
)
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
updatedAt maydoni hujjatda yo’q edi — $set uni qo’shib qo’ydi.
Mavjud maydonni o’zgartirish va yangisini qo’shish bir xil yoziladi.
Natija obyektini o’qish
Uchta son qaytadi va ular boshqa-boshqa narsani bildiradi:
| Maydon | Ma’nosi |
|---|---|
matchedCount |
Filtrga mos kelgan hujjatlar soni |
modifiedCount |
Haqiqatan o’zgargan hujjatlar soni |
upsertedCount |
Yangi yaratilgan hujjatlar soni |
Ular har doim ham teng bo’lmaydi:
db.products.updateOne(
{ name: "Daftar" },
{ $set: { price: 9500 } }
)
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 0,
upsertedCount: 0
}
Hujjat topildi, lekin narx allaqachon 9500 edi — o’zgarish bo’lmadi.
$set siz yozish — butun hujjatni almashtirish
Bu darsning eng muhim tuzog’i:
db.products.replaceOne(
{ name: "Shum bola" },
{ name: "Shum bola", price: 31000 }
)
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
db.products.findOne({ name: "Shum bola" })
{
_id: ObjectId('671f8a1b2c3d4e5f6a7b8c33'),
name: 'Shum bola',
price: 31000
}
category va quantity maydonlari yo’qoldi. replaceOne hujjatni
butunlay yangisiga almashtiradi.
$inc — sonni oshirish va kamaytirish
Omborda soni bittaga kamaydi. Hozirgi qiymatni o’qib, bittani ayirib, qaytadan yozish mumkin edi — lekin ikki foydalanuvchi bir vaqtda shunday qilsa, bittasining o’zgarishi yo’qoladi.
$inc bu ishni bazaning o’zida bajaradi:
db.products.updateOne(
{ name: "Daftar" },
{ $inc: { quantity: -1 } }
)
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
db.products.findOne({ name: "Daftar" }, { name: 1, quantity: 1, _id: 0 })
{ name: 'Daftar', quantity: 149 }
Musbat son oshiradi:
db.products.updateOne(
{ name: "Daftar" },
{ $inc: { quantity: 50, viewCount: 1 } }
)
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
db.products.findOne({ name: "Daftar" }, { name: 1, quantity: 1, viewCount: 1, _id: 0 })
{ name: 'Daftar', quantity: 199, viewCount: 1 }
viewCount maydoni yo’q edi — $inc uni 0 deb hisoblab, 1 qilib
yaratdi.
updateMany — bir necha hujjat
updateOne filtrga mos birinchi hujjatni yangilaydi. Hammasini
o’zgartirish uchun updateMany:
db.products.updateMany(
{ category: "kitob" },
{ $set: { discount: 10 } }
)
{
acknowledged: true,
insertedId: null,
matchedCount: 3,
modifiedCount: 3,
upsertedCount: 0
}
db.products.find({ category: "kitob" }, { name: 1, discount: 1, _id: 0 })
[
{ name: "O'tkan kunlar", discount: 10 },
{ name: 'Mehrobdan chayon', discount: 10 },
{ name: 'Shum bola', discount: 10 }
]
Narxlarni 10 foizga oshirish:
db.products.updateMany(
{ category: "kanselyariya" },
{ $mul: { price: 1.1 } }
)
{
acknowledged: true,
insertedId: null,
matchedCount: 2,
modifiedCount: 2,
upsertedCount: 0
}
db.products.find({ category: "kanselyariya" }, { name: 1, price: 1, _id: 0 })
[
{ name: 'Daftar', price: 10450.000000000002 },
{ name: 'Ruchka', price: 4950.000000000001 }
]
$unset va $rename
Maydonni butunlay olib tashlash:
db.products.updateMany(
{ category: "kitob" },
{ $unset: { discount: "" } }
)
{
acknowledged: true,
insertedId: null,
matchedCount: 3,
modifiedCount: 3,
upsertedCount: 0
}
db.products.findOne({ name: "O'tkan kunlar" }, { name: 1, discount: 1, _id: 0 })
{ name: "O'tkan kunlar" }
$unset dagi "" qiymati ishlatilmaydi — sintaksis shuni talab qiladi,
o’rniga nima yozilishi ahamiyatsiz.
Maydon nomini o’zgartirish:
db.products.updateMany({}, { $rename: { quantity: "stockCount" } })
{
acknowledged: true,
insertedId: null,
matchedCount: 5,
modifiedCount: 5,
upsertedCount: 0
}
db.products.findOne({ name: "Ruchka" }, { name: 1, stockCount: 1, _id: 0 })
{ name: 'Ruchka', stockCount: 280 }
Bu — SQL’dagi ALTER TABLE ning MongoDB muqobili. Farqi: bu yerda hujjatlar birma-bir yangilanadi, jadval tuzilishi o’zgarmaydi.
Nomni orqaga qaytaramiz, keyingi misollar uchun:
db.products.updateMany({}, { $rename: { stockCount: "quantity" } })
{
acknowledged: true,
insertedId: null,
matchedCount: 5,
modifiedCount: 5,
upsertedCount: 0
}
upsert — yo’q bo’lsa yarat
Ba’zan “bor bo’lsa yangila, yo’q bo’lsa qo’sh” kerak bo’ladi. Ikki
buyruq yozish o’rniga upsert bayrog’i qo’yiladi:
db.products.updateOne(
{ name: "Markerlar" },
{ $set: { category: "kanselyariya", price: 15000, quantity: 40 } },
{ upsert: true }
)
{
acknowledged: true,
insertedId: ObjectId('671f8b2c3d4e5f6a7b8c9d36'),
matchedCount: 0,
modifiedCount: 0,
upsertedCount: 1
}
matchedCount: 0 — topilmadi, upsertedCount: 1 — yaratildi. Yangi
hujjatga filtrdagi name ham qo’shildi:
db.products.findOne({ name: "Markerlar" }, { _id: 0 })
{ name: 'Markerlar', category: 'kanselyariya', price: 15000, quantity: 40 }
Shu buyruqni takrorlasangiz, endi yangilanish bo’ladi:
db.products.updateOne(
{ name: "Markerlar" },
{ $set: { price: 16000 } },
{ upsert: true }
)
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
Amaliy mashq
Yuqoridagi shop bazasida bajaring:
updateOneva$setbilan bitta mahsulot narxini o’zgartiring vamatchedCounthamdamodifiedCountni solishtiring.- Xuddi shu buyruqni ikkinchi marta yurgizing —
modifiedCountnega0bo’lganini tushuntiring. - Mavjud bo’lmagan nom bilan
updateOnechaqiring va xato chiqmasligiga ishonch hosil qiling. $incbilan bitta mahsulotquantitysini-3ga o’zgartiring, so’ng mavjud bo’lmagansoldCountmaydonini$incbilan oshiring.updateManybilan butun kategoriyagaisFeatured: falsemaydonini qo’shing, keyin$unsetbilan uni olib tashlang.upsert: truebilan yangi mahsulot yarating va shu buyruqni takrorlab,upsertedCountdanmodifiedCountga o’tishni kuzating.
3-qadam eng ko’p sezilmay qoladigan xatoni ko’rsatadi: yangilanmagan hujjat ham “muvaffaqiyatli” javob qaytaradi.
Qisqacha xulosa
updateOnebitta,updateManybarcha mos hujjatlarni yangilaydi.- O’zgarish har doim operator bilan yoziladi — eng ko’p ishlatilgani
$set. $setmavjud maydonni o’zgartiradi, bo’lmaganini qo’shadi;replaceOneesa hujjatni butunlay almashtiradi.matchedCounttopilganni,modifiedCounthaqiqatan o’zgarganni bildiradi; filtr bo’sh qaytsa ham xato chiqmaydi.$incsonni bazaning o’zida atomar oshiradi,$mulko’paytiradi.$unsetmaydonni o’chiradi,$renamenomini o’zgartiradi.upsert: truetopilmasa yangi hujjat yaratadi — filtri yagona maydon bo’yicha bo’lsin.
Keyingi darsda hujjat o’chirish —
deleteOne, deleteMany va o’chirishdagi xavfsizlik.