MongoDB Delete

Remove documents from your collections

🗑️ Deleting Documents

Deleting documents in MongoDB means removing data from collections permanently. Use deleteOne() to remove a single document or deleteMany() to delete multiple documents matching your criteria at once.


// Delete one document
db.users.deleteOne({ name: "Alice" })

// Delete multiple documents
db.users.deleteMany({ age: { $lt: 18 } })

// Delete all documents
db.users.deleteMany({})
                                    

Delete Methods

MongoDB provides methods to remove documents from collections. Deletions are permanent and cannot be undone, so always use filters carefully to avoid removing wrong data.

1️⃣

deleteOne()

Delete first matching document

deleteOne(filter)
📚

deleteMany()

Delete all matching documents

deleteMany(filter)
⚠️

Permanent

Deletions cannot be undone

// No undo available
📊

Delete Count

Returns number of deleted docs

deletedCount: 5

🔹 Delete One Document

Use deleteOne() to remove the first document matching your filter:

// Delete user by name
db.users.deleteOne({ name: "Alice" })

// Delete by _id
db.users.deleteOne({ _id: 1 })

// Delete first document matching condition
db.products.deleteOne({ stock: 0 })

Output:

✓ 1 document deleted

deletedCount: 1

🔹 Delete Many Documents

Use deleteMany() to remove all documents matching your filter:

// Delete all users from Boston
db.users.deleteMany({ city: "Boston" })

// Delete products under $10
db.products.deleteMany({ price: { $lt: 10 } })

// Delete old orders
db.orders.deleteMany({ 
    orderDate: { $lt: new Date("2023-01-01") }
})

Output:

✓ 23 documents deleted

deletedCount: 23

🔹 Delete All Documents

Remove all documents from a collection by passing an empty filter:

// Delete all documents in collection
db.tempData.deleteMany({})

// Verify collection is empty
db.tempData.countDocuments()

Output:

✓ All documents deleted

deletedCount: 150

Remaining: 0

Note:

This removes all documents but keeps the collection. Use db.collection.drop() to remove the entire collection.

🔹 Delete with Query Operators

Use query operators to target specific documents for deletion:

// Delete users younger than 18
db.users.deleteMany({ age: { $lt: 18 } })

// Delete inactive accounts
db.accounts.deleteMany({ 
    lastLogin: { $lt: new Date("2023-01-01") }
})

// Delete with multiple conditions
db.products.deleteMany({
    stock: 0,
    discontinued: true
})

// Delete with OR condition
db.orders.deleteMany({
    $or: [
        { status: "cancelled" },
        { status: "refunded" }
    ]
})

Output:

✓ Inactive accounts deleted

deletedCount: 47

🔹 Delete and Return Document

Use findOneAndDelete() to delete and return the deleted document:

// Delete and return document
const deletedUser = db.users.findOneAndDelete(
    { name: "Bob" }
)

// Delete and return with sort
const oldestOrder = db.orders.findOneAndDelete(
    { status: "completed" },
    { sort: { orderDate: 1 } }
)

// Returns the deleted document
print(deletedUser)

Output:

{ _id: 2, name: "Bob", age: 30, city: "Boston" }

🔹 Check Before Deleting

Always verify what you're about to delete before executing:

// Step 1: Find documents to delete
db.users.find({ age: { $lt: 18 } })

// Step 2: Count how many will be deleted
db.users.countDocuments({ age: { $lt: 18 } })

// Step 3: If count looks correct, delete
db.users.deleteMany({ age: { $lt: 18 } })

// Step 4: Verify deletion
db.users.countDocuments({ age: { $lt: 18 } })

Output:

Before: 12 documents

Deleted: 12 documents

After: 0 documents

🔹 Delete vs Drop

Understand the difference between deleting documents and dropping collections:

deleteMany({}) vs drop():

  • deleteMany({}): Removes all documents, keeps collection and indexes
  • drop(): Removes entire collection including indexes
  • Performance: drop() is faster for removing everything
// Delete all documents (keeps collection)
db.logs.deleteMany({})

// Drop entire collection
db.logs.drop()

// Verify collection is gone
show collections

🔹 Safe Deletion Practices

Follow these best practices when deleting data:

  • Always use filters: Never delete without a filter unless intentional
  • Test queries first: Use find() to verify what will be deleted
  • Backup important data: Create backups before bulk deletions
  • Use transactions: For critical operations that need rollback capability
  • Soft delete option: Consider marking as deleted instead of removing
// Soft delete (mark as deleted)
db.users.updateOne(
    { _id: 1 },
    { 
        $set: { 
            deleted: true,
            deletedAt: new Date()
        }
    }
)

// Query only active users
db.users.find({ deleted: { $ne: true } })

🔹 Complete Example

Here's a practical example of various delete operations:

// Switch to database
use ecommerceDB

// Delete single cancelled order
db.orders.deleteOne({ 
    orderId: "ORD-12345",
    status: "cancelled"
})

// Delete all expired coupons
const expiredCount = db.coupons.deleteMany({
    expiryDate: { $lt: new Date() }
})
print("Expired coupons deleted: " + expiredCount.deletedCount)

// Delete products with no stock for 6+ months
db.products.deleteMany({
    stock: 0,
    lastRestocked: { 
        $lt: new Date(Date.now() - 180 * 24 * 60 * 60 * 1000)
    }
})

// Delete guest user sessions older than 24 hours
db.sessions.deleteMany({
    userType: "guest",
    createdAt: { 
        $lt: new Date(Date.now() - 24 * 60 * 60 * 1000)
    }
})

// Delete and archive old reviews
const oldReviews = db.reviews.find({
    createdAt: { $lt: new Date("2020-01-01") }
}).toArray()

// Save to archive collection
db.archivedReviews.insertMany(oldReviews)

// Delete from main collection
db.reviews.deleteMany({
    createdAt: { $lt: new Date("2020-01-01") }
})

// Verify deletions
print("Orders: " + db.orders.countDocuments())
print("Coupons: " + db.coupons.countDocuments())
print("Products: " + db.products.countDocuments())

Output:

✓ 1 order deleted

✓ 34 expired coupons deleted

✓ 12 products deleted

✓ 89 sessions deleted

✓ Old reviews archived

🧠 Test Your Knowledge

What happens when you use deleteMany({}) with an empty filter?