MongoDB Delete Document

MongoDB provides multiple methods for deleting documents, allowing you to delete single or multiple documents.

Delete Single Document

deleteOne() Method

db.collection.deleteOne(filter, options)

Basic Example

// Delete first matching document
db.users.deleteOne({ name: "John" })

Return Result

{
  "acknowledged": true,
  "deletedCount": 1
}

Delete Multiple Documents

deleteMany() Method

db.collection.deleteMany(filter, options)

Basic Example

// Delete all matching documents
db.users.deleteMany({ status: "inactive" })

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

Delete Conditions

Exact Match Delete

// Delete document where name is "John"
db.users.deleteOne({ name: "John" })

// Delete documents matching multiple conditions
db.users.deleteMany({ status: "banned", createdAt: { $lt: new Date("2023-01-01") } })

Delete Using Operators

// Delete documents where age is less than 18
db.users.deleteMany({ age: { $lt: 18 } })

// Delete users with specific status
db.users.deleteMany({ status: { $in: ["deleted", "banned"] } })

// Delete documents created more than one year ago
db.logs.deleteMany({
  createdAt: { $lt: new Date(Date.now() - 365 * 24 * 60 * 60 * 1000) }
})

Find and Delete

findOneAndDelete() Method

db.collection.findOneAndDelete(filter, options)

Basic Example

// Find and delete, return deleted document
var deletedDoc = db.users.findOneAndDelete({ name: "John" })
printjson(deletedDoc)

Delete with Sort

// Delete oldest user
db.users.findOneAndDelete(
  {},
  { sort: { createdAt: 1 } }
)

// Delete newest user
db.users.findOneAndDelete(
  {},
  { sort: { createdAt: -1 } }
)

Projection of Returned Fields

// Delete and return specified fields
db.users.findOneAndDelete(
  { name: "John" },
  { projection: { name: 1, email: 1 } }
)

Delete Options

writeConcern

db.users.deleteOne(
  { name: "John" },
  {
    writeConcern: {
      w: "majority",
      j: true,
      wtimeout: 5000
    }
  }
)

Collation

db.users.deleteOne(
  { name: "john" },
  { collation: { locale: "en", strength: 2 } }
)

Bulk Delete

Batch Delete (Large Data)

// Batch delete to avoid long locks
var batchSize = 1000
var deleted = 0

while (true) {
  var result = db.oldlogs.deleteMany(
    { createdAt: { $lt: new Date("2023-01-01") } },
    { limit: batchSize }
  )
  
  deleted += result.deletedCount
  print("Deleted:", deleted)
  
  if (result.deletedCount < batchSize) {
    break
  }
  
  // Brief sleep to reduce database load
  sleep(100)
}

print("Total deleted:", deleted)

Delete vs Drop Collection Comparison

OperationCommandResult
Delete all documentsdeleteMany({})Documents deleted, collection kept
Drop collectiondrop()Collection and documents deleted
Empty collectionremove({})Same as deleteMany
// Delete all documents (keep collection and indexes)
db.users.deleteMany({})

// Drop collection (delete all content and indexes)
db.users.drop()

Pre-Delete Confirmation

Safe Delete Function

function safeDelete(filter, collection) {
  collection = collection || "users"
  var col = db.getCollection(collection)
  
  // Count documents to delete
  var count = col.countDocuments(filter)
  
  if (count === 0) {
    print("No matching documents")
    return 0
  }
  
  print("Will delete", count, "documents")
  print("Query filter:", JSON.stringify(filter))
  
  // Show first 5 for preview
  print("Preview first 5:")
  col.find(filter).limit(5).forEach(function(doc) {
    printjson(doc)
  })
  
  // Execute delete
  var result = col.deleteMany(filter)
  print("Actually deleted:", result.deletedCount, "documents")
  
  return result.deletedCount
}

// Usage
safeDelete({ status: "inactive" }, "users")

Implement Soft Delete

// Add deleted flag instead of actually deleting
db.users.updateOne(
  { _id: ObjectId("...") },
  {
    $set: {
      deleted: true,
      deletedAt: new Date()
    }
  }
)

// Filter out deleted when querying
db.users.find({ deleted: { $ne: true } })

Soft Delete Advantages

  • Data is recoverable
  • Historical records preserved
  • Meets audit requirements

Delete Examples

Periodic Cleanup Task

// Delete logs older than 30 days
db.appLogs.deleteMany({
  createdAt: {
    $lt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)
  }
})

// Delete users who deleted account more than 90 days ago
db.users.deleteMany({
  status: "deleted",
  deletedAt: {
    $lt: new Date(Date.now() - 90 * 24 * 60 * 60 * 1000)
  }
})

Deduplication Keep Latest

// Delete duplicates, keep latest
var duplicates = db.users.aggregate([
  { $group: { _id: "$email", count: { $sum: 1 }, ids: { $push: "$_id" } } },
  { $match: { count: { $gt: 1 } } }
])

duplicates.forEach(function(doc) {
  // Keep first (latest), delete others
  var idsToDelete = doc.ids.slice(1)
  db.users.deleteMany({ _id: { $in: idsToDelete } })
})

Summary

Key points for deleting documents:

  • deleteOne() for single document deletion
  • deleteMany() for multiple document deletion
  • findOneAndDelete() to find and delete, can return document
  • Large batch deletes should be done in chunks
  • Consider using soft delete to preserve data

In the next chapter, we will learn about MongoDB Operators.