deleteOne ve deleteMany ile Belgeleri Güvenle Silme
Öğrenenler, tekil veya birden çok belgeyi kaldıracak ve yanlışlıkla toplu silme yapılmasını önleme stratejilerini tartışacaktır.
deleteOne ve deleteMany ile Belgeleri Güvenle Silme, CoddyKit'te ücretsiz bir MongoDB Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, MongoDB Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. MongoDB Academy kursu toplamda 4 dersten oluşur.
MongoDB'de Kalıcı Silme
MongoDB belgeleri kaldırmak için iki yöntem sunar:
- deleteOne(filter) — filtreyle eşleşen ilk belgeyi kaldırır ve
{ acknowledged, deletedCount }döndürür - deleteMany(filter) — filtreyle eşleşen tüm belgeleri kaldırır ve toplam
deletedCountdeğerini döndürür
SQL'deki DELETE'in aksine MongoDB'deki silme işlemleri kalıcı ve anlıktır; işlem onaylandıktan sonra işleme dayalı bir geri alma yoktur (henüz tamamlanmamış birden çok belgeli işlem içindeyseniz bu durum geçerli değildir). Silme işlemlerinde her zaman dikkatle hazırlanmış, hedefi belirli filtreler kullanın.
// deleteOne: removes first matching document
const res1 = await db.collection('sessions').deleteOne(
{ token: expiredToken }
);
console.log(res1.deletedCount); // 0 or 1
// deleteMany: removes all matching documents
const res2 = await db.collection('sessions').deleteMany(
{ expiresAt: { $lt: new Date() } }
);
console.log(res2.deletedCount); // 0 or moredeleteMany({}) İşleminin Tehlikesi
deleteMany içinde boş bir filtre olan {}, koleksiyondaki her belgeyi siler. Bu, SQL'deki TRUNCATE TABLE ile eşdeğerdir ve MongoDB'de yanlışlıkla gerçekleştirilebilecek en tehlikeli işlemlerden biridir. SQL'in aksine bir onay istemi yoktur; işlem her şeyi doğrudan siler.
MongoDB varsayılan olarak bir 'geçici silme' mekanizması sunmaz; silerseniz veriler yok olur. Kazaları önlemek için en iyi uygulamalar: kapsamlı bir deleteMany çalıştırmadan önce filtreyi her zaman iki kez denetleyin, önce countDocuments ile filtreyi sınayın ve yönetim araçlarında açık bir onay gerektirmeyi değerlendirin.
// DANGER: Deletes ALL documents in the collection!
db.users.deleteMany({});
// Before you run deleteMany - always verify your filter first:
// Step 1: Count what will be deleted
const count = await db.collection('users').countDocuments(
{ status: 'temp' } // Your intended filter
);
console.log('Will delete:', count, 'documents');
// Step 2: Only delete after reviewing the count
if (count > 0 && count < SAFE_LIMIT) {
await db.collection('users').deleteMany({ status: 'temp' });
}Geçici Silme Kalıbı
Birçok uygulama fiziksel silme yerine soft delete uygular: belgeyi kaldırmak yerine bir deletedAt zaman damgası alanı (veya isDeleted: true işareti) eklenir ve güncellenir. Belge veritabanında kalır ancak silinen kayıtlar filtrelenerek normal sorguların dışında bırakılır.
Soft delete şu olanakları sağlar: silme işlemini geri alma/geri yükleme işlevi, denetim izleri (neyi, kimin ve ne zaman sildiği), kalıcı silmeyi erteleme (30 günden eski kayıtları temizleme) ve veri saklama politikalarına uyumluluk. Dezavantajı ise sorguların her zaman deletedAt: { $exists: false } filtresini içermesi gerekmesidir; bu filtreyi unutmak kolaydır.
// Soft delete: mark as deleted instead of removing
async function softDelete(collection, id) {
await db.collection(collection).updateOne(
{ _id: new ObjectId(id) },
{ $set: { deletedAt: new Date(), deletedBy: currentUserId } }
);
}
// All queries must exclude deleted records:
db.posts.find({ deletedAt: { $exists: false } });
// Purge records deleted more than 30 days ago:
const cutoff = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
db.posts.deleteMany({ deletedAt: { $lt: cutoff } });findOneAndDelete: Silme ve Döndürme
findOneAndDelete(filter, options), tek bir işlem içinde atomik olarak bir belge bulur, siler ve silinen belgeyi döndürür. Bu yöntem, silinen belgenin verilerini işlemeniz gerektiğinde (örneğin sıraya alınmış bir görevi alma ve kaldırma sırasında) kullanışlıdır.
Döndürülen değer, silme işleminden önceki haliyle belgedir. Filtreyle eşleşen belge yoksa null döndürülür. Bu atomik bulma-silme kalıbı, bir belgeyi okuma ile silme arasındaki yarış durumunu ortadan kaldırır.
// Atomic pop from a task queue
async function claimNextTask() {
const task = await db.collection('taskQueue').findOneAndDelete(
{ status: 'pending' },
{ sort: { priority: -1, createdAt: 1 } } // Highest priority, oldest first
);
if (!task) {
return null; // Queue is empty
}
// Process the task - it's already removed from the queue
await processTask(task);
return task._id;
}Kademeli Silmeler: Referansları Yönetme
MongoDB, SQL veritabanları gibi yabancı anahtar kısıtlamalarını zorunlu kılmaz. Bir üst belgeyi (örneğin bir user) silerseniz, diğer koleksiyonlarda bu kullanıcının _id değerine başvuran belgeler (örneğin orders ve posts) artık geçersiz bir referansla var olmaya devam eder.
Kademeli silmeleri uygulama kodunuzda veya bir işlem içinde açıkça yönetin: önce üst belgeyi, ardından ilgili tüm alt belgeleri silin. Atomiklik önemliyse kademeli silmeleri her zaman bir işlem içine alın; üst belgenin silinmesini, alt belgelerin temizlenmesinin ise başarısız olmasını istemezsiniz.
// Cascading delete with transaction
async function deleteUser(userId) {
const session = client.startSession();
try {
await session.withTransaction(async () => {
const id = new ObjectId(userId);
// Delete user
await db.collection('users').deleteOne({ _id: id }, { session });
// Delete all user's posts
await db.collection('posts').deleteMany({ authorId: id }, { session });
// Delete user's sessions
await db.collection('sessions').deleteMany({ userId: id }, { session });
});
console.log('User and all related data deleted');
} finally {
await session.endSession();
}
}Otomatik Süre Dolumu için TTL Dizinleri
Zamanlanmış silme görevleri yazmak yerine MongoDB, belgeleri belirli bir sürenin ardından otomatik olarak silen TTL (Time-To-Live) dizinleri sağlar. Bir Date alanındaki TTL dizini, bu alanda saklanan tarihten belirtilen sayıda saniye sonra belgeleri siler.
TTL dizinleri şu veriler için idealdir: oturum belirteçleri, e-posta doğrulama kodları, geçici hız sınırı kayıtları, görev kuyruğu öğeleri ve kısa ömürlü tüm veriler. Silme işlemi arka planda çalışır; MongoDB'nin TTL izleme iş parçacığı her 60 saniyede bir denetim yaptığından silme işlemi hemen gerçekleşmez, zaman içinde tutarlı hale gelir.
// Create a TTL index: delete sessions 24 hours after createdAt
db.sessions.createIndex(
{ createdAt: 1 },
{ expireAfterSeconds: 86400 } // 24h in seconds
);
// Sessions are automatically deleted 24h after their createdAt date
// No cron job needed!
// For user-defined expiry per document:
db.verificationCodes.createIndex(
{ expiresAt: 1 },
{ expireAfterSeconds: 0 } // Delete at the date stored in expiresAt
);
// Each document controls its own expiry: expiresAt: new Date(Date.now() + 3600000)Toplu Silmeler ve Performans
Çok sayıda belgeyi silerken, boş (veya geniş) filtreye sahip tek bir deleteMany koleksiyonu kilitleyebilir ve işlem süresince diğer işlemleri etkileyebilir. Üretim ortamlarında büyük toplu silmeler için:
- Küçük parçalara bölün: her seferinde 1000 belgeyi, gruplar arasında kısa bir beklemeyle döngü içinde silin
- Dizinlenmiş alana göre filtreleyin: koleksiyon taramasını önlemek için filtreye her zaman dizinlenmiş bir alan ekleyin
- Düşük yoğunluklu saatlerde zamanlayın: büyük temizleme işlemlerini trafiğin az olduğu saatlerde çalıştırın
// Batched deletion of old logs (prevents locking)
async function purgeOldLogs(cutoffDate) {
const BATCH_SIZE = 1000;
let totalDeleted = 0;
while (true) {
const result = await db.collection('logs').deleteMany(
{ createdAt: { $lt: cutoffDate } },
{ limit: BATCH_SIZE } // Note: deleteMany has no built-in limit
// Instead, use find + deleteOne in a loop for true batching
);
totalDeleted += result.deletedCount;
if (result.deletedCount === 0) break;
await new Promise(r => setTimeout(r, 100)); // Brief pause between batches
}
return totalDeleted;
}Koleksiyonu Bırakma ve deleteMany Karşılaştırması
Bir koleksiyondaki tüm belgeleri kaldırmak için iki seçeneğiniz vardır:
db.collection.deleteMany({})— tüm belgeleri kaldırır ancak koleksiyonu dizinleri ve ayarlarıyla birlikte korur. Her belge silme işlemi işlem günlüğüne ayrı ayrı kaydedildiği için daha yavaştır.db.collection.drop()— tüm dizinler ve üst veriler dahil olmak üzere koleksiyonun tamamını kaldırır. Depolama dosyalarını doğrudan sildiği için büyük koleksiyonlarda çok daha hızlıdır. Bundan sonra koleksiyon artık var olmaz.
Yeni bir başlangıç yapmak istediğinizde (örneğin testData değerlerini sıfırlarken) drop() kullanın. Koleksiyonun dizin yapısını korumak istediğinizde deleteMany({}) kullanın.
// Slow: deletes each document individually (keeps collection + indexes)
await db.collection('testData').deleteMany({});
// Fast: drops entire collection (collection and indexes are gone)
await db.collection('testData').drop();
// Recreate with indexes after drop:
await db.collection('testData').createIndex({ email: 1 }, { unique: true });
// Or just start inserting - collection recreates on first insertToplu Silmeden Önce Onaylama Kalıbı
Toplu silmeler için savunmacı bir kodlama kalıbı şudur: silme işlemini gerçekleştirmeden önce her zaman bir deneme çalıştırması sayımı yapın ve sayı güvenlik eşiğini aşarsa isteğe bağlı olarak açık onay isteyin. Bu, özellikle yönetici betikleri ve geçiş görevleri için önemlidir.
Denetim amacıyla silme işlemini günlüğe kaydedin: işlemi kimin başlattığını, ne zaman başlattığını, kaç belgenin silindiğini ve hangi filtrenin kullanıldığını kaydedin. Bu, uyumluluk için bir kayıt oluşturur ve olay sonrası incelemeyi mümkün kılar.
async function safeDeleteMany(collection, filter, options = {}) {
const { dryRun = false, maxAllowed = 1000 } = options;
// Always count first
const count = await db.collection(collection).countDocuments(filter);
console.log(`[DRY RUN] Would delete ${count} documents from ${collection}`);
if (dryRun) return { wouldDelete: count };
if (count > maxAllowed) {
throw new Error(`Safety: ${count} > max allowed ${maxAllowed}. Pass override to proceed.`);
}
const result = await db.collection(collection).deleteMany(filter);
console.log(`[DELETED] ${result.deletedCount} from ${collection}`);
return result;
}Silmek Yerine Arşivleme
Kalıcı silme ve soft delete işlemlerinin her ikisine de bir alternatif arşivlemedir: eski belgeleri silmek yerine ayrı bir arşiv koleksiyonuna taşıyın. Böylece geçmiş verileri denetim veya analiz için korurken birincil koleksiyonu küçük ve hızlı tutarsınız.
Arşivleme için toplama işlem hattının $merge veya $out aşamasını kullanın, ardından birincil koleksiyondan silin. Atlas Data Federation, S3 üzerindeki arşiv koleksiyonlarını sorgulayabilir ve yüksek hacimli geçmiş verilerin uygun maliyetle uzun süreli depolanmasını sağlar.
// Archive old orders then delete from primary collection
async function archiveOldOrders(beforeDate) {
// Step 1: Copy old orders to archive collection
await db.collection('orders').aggregate([
{ $match: { createdAt: { $lt: beforeDate }, status: 'completed' } },
{ $merge: { into: 'orders_archive', whenMatched: 'keepExisting' } }
]).toArray();
// Step 2: Delete them from primary collection
const del = await db.collection('orders').deleteMany({
createdAt: { $lt: beforeDate },
status: 'completed'
});
console.log('Archived and deleted:', del.deletedCount);
}Silinen Verileri Yedeklerden Geri Yükleme
Yanlışlıkla silme gerçekleştiğinde ve soft delete uygulanmamış olduğunda, kurtarma seçenekleriniz yedekleme stratejinize bağlıdır:
- MongoDB Atlas: sürekli yedekten belirli bir saniyeye kadar zamanda belirli bir noktaya geri yükleme
- Çoğaltma kümesi işlem günlüğü: işlem günlüğü ilgili zaman aralığını hâlâ içeriyorsa, işlemleri belirli bir zaman damgasına kadar yeniden oynatma
- mongodump yedekleri: son dökümden geri yükleme; bu işlem saatlerce verinin kaybedilmesine yol açabilir
Temel çıkarım şudur: hiçbir yedekleme stratejisi dikkatli silme uygulamalarının yerini tutmaz. İşlem günlüğü aralığı (Atlas'ta genellikle 24-72 saat), size bir güvenlik ağı sağlar; ancak dikkatli filtreler ve soft delete kullanarak önlemek, her zaman kurtarmaktan daha iyidir.
// Atlas point-in-time restore via Atlas API or UI
// No mongosh command - done through Atlas console or API
// Using oplog to find what was deleted (expert operation)
// Connect to replica set and inspect oplog:
use local
db.oplog.rs.find({
op: 'd', // delete operation
ns: 'myapp.users', // your namespace
wall: { : new Date(Date.now() - 3600000) } // last hour
}).sort({ ts: -1 });
// Each entry shows the _id of the deleted documentKısa Kontrol
Bu dersteki MongoDB ve NoSQL Veritabanları kavramlarını anlayıp anlamadığınızı test edin.
Ders Özeti
Bu derste şunları öğrendiniz: deleteOne ve deleteMany kalıcıdır—önce filtrenizi her zaman countDocuments ile doğrulayın ve açıkça amaçlamadığınız sürece deleteMany({}) komutunu asla çalıştırmayın; soft delete (deletedAt ile işaretleme), geri alma, denetim izleri ve kademeli temizlemeler sağladığı için kullanıcıya sunulan içerikler açısından daha güvenlidir; ayrıca TTL dizinleri, zamanlanmış görevler olmadan belgelerin süresinin otomatik olarak dolmasını sağlar ve oturumlar, doğrulama kodları ve geçici kayıtlar için idealdir. Böylece Belgeleri Güncelleme ve Silme kursu tamamlanıyor; sırada verileri, gömme ve referans kullanma stratejileriyle modelleme var.
Yapay zeka eğitmeniyle JavaScript öğren — ücretsiz
Tarayıcında gerçek kod yaz ve çalıştır, 7/24 yapay zeka eğitmeninden anında yardım al; web'de ya da uygulamada kaldığın yerden devam et.
- Kurslar
- 30
- Dersler
- 120
Sıkça Sorulan Sorular
“deleteOne ve deleteMany ile Belgeleri Güvenle Silme” dersi ücretsiz mi?
Evet — “deleteOne ve deleteMany ile Belgeleri Güvenle Silme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve MongoDB Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. MongoDB Academy kursu toplamda 4 dersten oluşur.
“deleteOne ve deleteMany ile Belgeleri Güvenle Silme” dersinde ne öğreneceğim?
Öğrenenler, tekil veya birden çok belgeyi kaldıracak ve yanlışlıkla toplu silme yapılmasını önleme stratejilerini tartışacaktır. MongoDB Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
MongoDB Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te MongoDB Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.
“deleteOne ve deleteMany ile Belgeleri Güvenle Silme” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu MongoDB Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her MongoDB Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- $set ve $unset ile updateOne ve updateMany
- Artırma, Çarpma ve Min/Max Operatörleri
- Dizi Güncelleme Operatörleri: $push, $pull, $addToSet
- deleteOne ve deleteMany ile Belgeleri Güvenle Silme