MongoDB hujjat o'chirish: deleteOne va deleteMany
O’chirish CRUD amallarining eng qisqasi va eng xavflisi. Qo’shishda xato qilsangiz ortiqcha hujjat qoladi, yangilashda eski qiymat yo’qoladi. O’chirishda esa ma’lumot butunlay ketadi — MongoDB’da “bekor qilish” tugmasi yo’q.
Shuning uchun bu darsda sintaksisdan ko’ra ehtiyot choralari ko’proq joy egallaydi.
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: 9500, quantity: 0 },
{ name: "Ruchka", category: "kanselyariya", price: 4500, quantity: 280 },
{ name: "Eskirgan katalog", category: "arxiv", price: 0, quantity: 0 }
])
{
acknowledged: true,
insertedIds: {
'0': ObjectId('671f9a1b2c3d4e5f6a7b8c41'),
'1': ObjectId('671f9a1b2c3d4e5f6a7b8c42'),
'2': ObjectId('671f9a1b2c3d4e5f6a7b8c43'),
'3': ObjectId('671f9a1b2c3d4e5f6a7b8c44'),
'4': ObjectId('671f9a1b2c3d4e5f6a7b8c45'),
'5': ObjectId('671f9a1b2c3d4e5f6a7b8c46')
}
}
Oltin qoida: avval find, keyin delete
O’chirishdan oldin har doim bir qadam qo’ying — o’sha filtr bilan
find chaqiring:
db.products.find({ category: "arxiv" }, { name: 1, _id: 0 })
[ { name: 'Eskirgan katalog' } ]
Bitta hujjat — kutilganidek. Endi o’chirish xavfsiz:
db.products.deleteOne({ category: "arxiv" })
{ acknowledged: true, deletedCount: 1 }
deleteOne — bitta hujjat
deleteOne filtrga mos birinchi hujjatni o’chiradi:
db.products.deleteOne({ name: "Daftar" })
{ acknowledged: true, deletedCount: 1 }
Natija obyektida bitta son bor: deletedCount.
Hech nima topilmasa xato chiqmaydi:
db.products.deleteOne({ name: "Mavjud emas" })
{ acknowledged: true, deletedCount: 0 }
deleteMany — mos kelganlarning hammasi
db.products.find({ quantity: 0 }, { name: 1, quantity: 1, _id: 0 })
[]
Bo’sh — Shum bola va Daftar allaqachon o’chirilgan. Yangi ma’lumot
qo’shamiz va deleteMany ni sinaymiz:
db.products.insertMany([
{ name: "Eski jurnal", category: "arxiv", price: 5000, quantity: 0 },
{ name: "Eski gazeta", category: "arxiv", price: 2000, quantity: 0 }
])
{
acknowledged: true,
insertedIds: {
'0': ObjectId('671f9b2c3d4e5f6a7b8c9d47'),
'1': ObjectId('671f9b2c3d4e5f6a7b8c9d48')
}
}
db.products.deleteMany({ category: "arxiv" })
{ acknowledged: true, deletedCount: 2 }
Operatorli filtr ham ishlaydi:
db.products.deleteMany({ price: { $lt: 5000 } })
{ acknowledged: true, deletedCount: 1 }
db.products.find({}, { name: 1, price: 1, _id: 0 })
[
{ name: "O'tkan kunlar", price: 45000 },
{ name: 'Mehrobdan chayon', price: 38000 }
]
Eng xavfli buyruq: bo’sh filtr
db.products.deleteMany({})
Bu buyruq butun kolleksiyani bo’shatadi. Xato bermaydi, tasdiqlashni so’ramaydi, ogohlantirmaydi.
Amalda bo’sh filtr kerak bo’lsa, avval nechta hujjat borligini ko’ring:
db.products.countDocuments({})
2
Son kutganingizga mos kelsa, davom etasiz.
drop — butun kolleksiyani o’chirish
deleteMany({}) hujjatlarni o’chiradi, kolleksiyaning o’zi qoladi.
drop() esa kolleksiyani butunlay olib tashlaydi:
db.tests.insertOne({ name: "sinov" })
db.tests.drop()
true
show collections
products
| Buyruq | Hujjatlar | Kolleksiya | Indekslar |
|---|---|---|---|
deleteMany({}) |
O’chadi | Qoladi | Qoladi |
drop() |
O’chadi | O’chadi | O’chadi |
Bazani butunlay o’chirish:
use tempdb
db.dropDatabase()
{ ok: 1, dropped: 'tempdb' }
Yumshoq o’chirish
Ko’p loyihada ma’lumot haqiqatan o’chirilmaydi — u “o’chirilgan” deb belgilanadi. Buyurtma tarixi, foydalanuvchi hisobi, hisobot uchun kerakli yozuvlar shunday saqlanadi.
Belgilash yangilash amaliga aylanadi:
db.products.updateOne(
{ name: "Mehrobdan chayon" },
{ $set: { isDeleted: true, deletedAt: new Date() } }
)
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
Endi odatiy so’rovga shart qo’shiladi:
db.products.find({ isDeleted: { $ne: true } }, { name: 1, _id: 0 })
[ { name: "O'tkan kunlar" } ]
Bu yerda $ne: true ataylab tanlangan:
solishtirish operatorlari darsida
ko’rganingizdek, u isDeleted maydoni umuman yo’q hujjatlarni ham
qaytaradi. Eski hujjatlarga belgi qo’shish shart emas.
| Yondashuv | Afzalligi | Kamchiligi |
|---|---|---|
| Haqiqiy o’chirish | Joy bo’shaydi, baza toza | Ma’lumot qaytmaydi |
| Yumshoq o’chirish | Tiklash mumkin, tarix qoladi | Har so’rovga shart qo’shiladi |
Amaliy mashq
Yuqoridagi shop bazasida bajaring:
- Bitta mahsulotni o’chirishdan oldin o’sha filtr bilan
findchaqiring va nechta hujjat mos kelishini ko’ring. deleteOnebilan uni o’chiring vadeletedCountqiymatini tekshiring.- Mavjud bo’lmagan nom bilan
deleteOnechaqiring — xato chiqmasligiga ishonch hosil qiling. - Test uchun
tempkolleksiyasiga uchta hujjat qo’shing, so’ngdeleteManybilan filtrga mos ikkitasini o’chiring. db.temp.deleteMany()ni argumentsiz yozib, chiqqan xatoni o’qing, keyindb.temp.deleteMany({})bilan qolganini tozalang.- Bitta hujjatga
isDeleted: truebelgisini qo’yib, uni{ isDeleted: { $ne: true } }filtri chiqarib tashlashini tekshiring.
1-qadam odat bo’lib qolishi kerak: find bilan tekshirish o’chirishning
ajralmas qismi.
Qisqacha xulosa
deleteOnebitta,deleteManybarcha mos hujjatni o’chiradi.- Natijada faqat
deletedCountqaytadi; hech nima topilmasa xato chiqmaydi. - O’chirishdan oldin bir xil filtr bilan
findchaqiring — bu qoidani istisnosiz bajaring. deleteMany({})butun kolleksiyani bo’shatadi,deleteMany()argumentsiz esa xato beradi.drop()kolleksiyani indekslari bilan birga o’chiradi.dropDatabase()hozirgi tanlangan bazani o’chiradi — avvaldbbilan tekshiring.- Yumshoq o’chirish — hujjatni o’chirmay, belgi qo’yish; tiklash imkonini saqlaydi.
Keyingi darsda saralash va limit —
sort, limit va sahifalash.