deleteOne, deleteMany — xavfli holatlar
Muammodan boshlaylik
O'chirish — CRUD ning eng xavfli operatsiyasi. Qo'shish xato bo'lsa — ortiqcha yozuv qoladi, uni o'chirish mumkin. Yangilash xato bo'lsa — eski qiymatni qaytarish mumkin. Lekin o'chirish xato bo'lsa — ma'lumot yo'qoladi, va ko'pincha qaytarib bo'lmaydi.
Real kompaniyalarda production serverida hech kim db.users.deleteMany({}) kabi buyruqlarni ishlatmaydi. Buning uchun alohida himoya mexanizmlari bor. Bu darsda shu xavflarni ko'rsatamiz.
deleteOne — bitta document o'chirish
// _id bo'yicha o'chirish — eng xavfsiz usul
db.users.deleteOne({ _id: ObjectId("507f1f77bcf86cd799439011") })
// Boshqa filter bilan — birinchi mos kelganini o'chiradi
db.postlar.deleteOne({ status: "spam" })
Qaytarilgan natija
let natija = db.users.deleteOne({ _id: id })
// Topildi va o'chirildi:
{ acknowledged: true, deletedCount: 1 }
// Topilmadi:
{ acknowledged: true, deletedCount: 0 }
deletedCount: 0 — xato emas. Document shunchaki topilmadi.
O'chirilganini tekshirish uchun bu qiymatni tekshiring.
deleteMany — bir nechta document o'chirish
// 30 kundan eski sessiyalarni o'chirish
let otmish = new Date()
otmish.setDate(otmish.getDate() - 30)
db.sessiyalar.deleteMany({
yaratilgan: { $lt: otmish }
})
// Faol bo'lmagan foydalanuvchilarni o'chirish
db.users.deleteMany({
faol: false,
oxirgi_kirish: { $lt: otmish }
})
let natija = db.users.deleteMany({ faol: false })
// { acknowledged: true, deletedCount: 47 }
Eng xavfli holat — filtrsiz deleteMany
// ❌ HECH QACHON PRODUCTION DA QILMANG
db.users.deleteMany({})
// Barcha foydalanuvchilar o'chirildi — qaytarib bo'lmaydi
SQL da ham xuddi shunday xavf bor:
-- SQL da ham xuddi shunday
DELETE FROM users; -- barcha yozuvlar o'chadi (WHERE yo'q)
MongoDB va SQL ikkalasida ham qoidasi bir xil:
deleteMany({}) == DELETE FROM table;
Ikkalasi ham halokatli.
⚠️ Qoida:
deleteManydan oldin doimfindbilan tekshiring — nechta document o'chirilishini ko'ring. Keyin o'chiring.
// ✅ Oldin tekshirish
let son = db.users.countDocuments({ faol: false })
console.log(`O'chiriladigan: ${son} ta`) // 47 ta deb chiqdi
// Tasdiqlangandan keyin o'chirish
db.users.deleteMany({ faol: false })
findOneAndDelete — yuqorida ham ko'rdik
O'chirish va o'chirilgan documentni bir vaqtda olish uchun:
let o_chirilgan = await db.vaqtinchalik_fayllar.findOneAndDelete(
{ _id: fileId },
{ projection: { yo_l: 1, hajm: 1 } }
)
if (o_chirilgan) {
// Diskdan ham o'chirish
await fs.unlink(o_chirilgan.yo_l)
}
Soft Delete — professional yondashuv
Real loyihalarda deleteOne / deleteMany kamdan-kam ishlatiladi. Buning o'rniga soft delete — "o'chirilgan deb belgilash" usuli qo'llanadi.
Tasavvur qiling: foydalanuvchi akkauntini o'chirdi. Agar haqiqatan o'chirsangiz:
- Uning buyurtmalari, sharhlari "quvurdan" chiqib ketadi
- Ma'muriy hisobotlar buziladi
- Foydalanuvchi qayta kirmoqchi bo'lsa — yo'qolgan
Soft delete — documentni o'chirish o'rniga deleted: true va deletedAt: new Date() qo'yadi.
// ❌ Haqiqatan o'chirish — xavfli
db.users.deleteOne({ _id: userId })
// ✅ Soft delete — professional usul
db.users.updateOne(
{ _id: userId },
{
$set: {
deleted: true,
deletedAt: new Date()
}
}
)
// Soft delete bilan barcha so'rovlarda filter qo'shish kerak
db.users.find({ deleted: { $ne: true } }) // o'chirilmaganlar
// Yoki index bilan
db.users.find({ deleted: false })
Soft delete ning afzalliklari:
- Ma'lumot yo'qolmaydi — audit, hisobot, tiklanish uchun qoladi
- O'chirilgan narsani tiklash oson
- Tegishli ma'lumotlar (buyurtmalar, sharhlar) buzilmaydi
Kamchiliklari:
- Har bir so'rovga
deleted: falsefilter qo'shishni unutmaslik kerak - Collection hajmi oshadi
- Index lar murakkablashadi
💡 Maslahat: Mongoose da
mongoose-deleteplugin'i soft delete ni avtomatik boshqaradi — 57-darsda ko'ramiz.
dropCollection — collection ni butunlay o'chirish
// Collection ni butunlay o'chirish (barcha document + index lar)
db.vaqtinchalik.drop()
⚠️
drop()— o'chirilgan collection qaytarib bo'lmaydi. Indexlar ham yo'qoladi.
SQL bilan:
-- SQL
DROP TABLE vaqtinchalik; -- jadval butunlay o'chadi
TRUNCATE TABLE vaqtinchalik; -- faqat ma'lumotlar o'chadi, jadval qoladi
MongoDB da:
db.vaqtinchalik.drop() // collection butunlay o'chadi
db.vaqtinchalik.deleteMany({}) // ma'lumotlar o'chadi, collection qoladi
Tez-tez uchraydigan xatolar
deletedCount tekshirilmaydi
// ❌ O'chirilganmi yo'qmi bilmaymiz
await db.users.deleteOne({ _id: userId })
// ✅ Tekshirish
let natija = await db.users.deleteOne({ _id: userId })
if (natija.deletedCount === 0) {
throw new Error("Foydalanuvchi topilmadi")
}
String _id bilan o'chirish
// ❌ String sifatida berish — topilmaydi
db.users.deleteOne({ _id: "507f1f77bcf86cd799439011" })
// deletedCount: 0 — o'chirmadi
// ✅ ObjectId ga o'tkazish
const { ObjectId } = require("mongodb")
db.users.deleteOne({ _id: new ObjectId("507f1f77bcf86cd799439011") })
deleteMany — filter maydoni yo'q documentlar
// ❌ Agar ba'zi documentlarda "faol" maydoni umuman yo'q bo'lsa
db.users.deleteMany({ faol: false })
// Faqat faol: false bo'lganlar o'chadi
// faol maydoni yo'q documentlar qolib ketadi
// ✅ $ne — false yoki yo'q bo'lgan hammasi
db.users.deleteMany({ faol: { $ne: true } })
// faol: false ham, faol yo'q ham o'chadi
Xulosa
deleteOne— faqat birinchi mos kelganini o'chiradideleteMany— barcha moslarini o'chiradi — doim filter tekshiringdeleteMany({})— halokatli, production da hech qachon ishlatmang- Soft delete — real loyihalarda
deleteo'rnigadeleted: trueqo'yish professional yondashuv - O'chirishdan oldin
countDocumentsbilan tekshiring
Keyingi dars: 12-dars — bulkWrite — bir nechta operatsiyani birga bajarish