Soft delete pattern
A soft delete marks a document as deleted instead of removing it, so it can be restored or audited.
In this page:
Syntax
db.collection_name.updateOne(filter, { $set: { deletedAt: new Date() } })
db.collection_name.find({ deletedAt: { $exists: false } })
Soft delete pattern
Add a deleted flag or deletedAt date and filter it out of normal queries. Consider a partial index or TTL index to purge old soft-deleted data later. It costs storage and adds a filter to every query, so use it when history or undo matters.
Note:
Wrap the deleted filter in a helper so queries never forget it.
Example: Soft delete pattern
test> db.users.insertMany([{ _id: 1, name: "Ada", deletedAt: null }, { _id: 2, name: "Bob", deletedAt: null }])
{ acknowledged: true, insertedIds: { '0': 1, '1': 2 } }
test> db.users.updateOne({ _id: 2 }, { $set: { deletedAt: ISODate("2024-03-01T00:00:00Z") } })
{ acknowledged: true, matchedCount: 1, modifiedCount: 1 }
test> db.users.find({ deletedAt: null }, { name: 1, _id: 0 })
[ { name: 'Ada' } ]
test> db.users.updateOne({ _id: 2 }, { $set: { deletedAt: null } })
{ acknowledged: true, matchedCount: 1, modifiedCount: 1 }
test> db.users.countDocuments({ deletedAt: null })
2
⚠️ Run this in your own terminal or Node.js environment.
Related Topics
Common Mistakes
- Forgetting to filter deleted documents
- Keeping soft-deleted personal data forever
- Unique indexes clashing with deleted duplicates
Chapter Summary
- Mark deleted with a flag or date
- Filter them out of queries
- Allows restore and audit
- Purge old ones with TTL or jobs
🔒
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: