如何实现Mongoose文档标记为trash(true)后一个月自动删除?
解决方案:基于Mongoose实现假删除后延迟一个月自动清理
1. 调整Product Schema结构
添加trash标记字段和trashAt删除时间记录字段,同时创建条件TTL索引——仅对标记为已删除(trash: true)的文档生效,过期时间从trashAt开始计算。
const mongoose = require('mongoose'); const productSchema = new mongoose.Schema({ // 原有业务字段示例 name: String, price: Number, // 新增假删除相关字段 trash: { type: Boolean, default: false, index: true // 优化查询性能 }, trashAt: Date // 仅在标记为删除时赋值 }); // 创建条件TTL索引:仅trash=true的文档,从trashAt起1个月后自动删除 productSchema.index( { trashAt: 1 }, { expireAfterSeconds: 2592000, // 2592000秒 = 30天(1个月) partialFilterExpression: { trash: true } } ); const Product = mongoose.model('Product', productSchema);
2. 修改删除操作逻辑
用户执行删除时,不直接删除文档,而是更新trash状态并记录trashAt时间:
// 软删除产品的业务逻辑 async function softDeleteProduct(productId) { return await Product.findByIdAndUpdate( productId, { trash: true, trashAt: new Date() // 记录标记删除的时间点 }, { new: true } // 返回更新后的文档 ); }
3. 前端数据查询逻辑
- 正常展示列表:过滤掉已标记删除的文档
// 获取正常展示的产品列表 async function getActiveProducts() { return await Product.find({ trash: false }); }
- 回收站列表:仅展示标记为删除的文档
// 获取回收站中的产品列表 async function getTrashedProducts() { return await Product.find({ trash: true }); }
关键细节说明
- 条件TTL索引:通过
partialFilterExpression限定只有trash: true的文档才会被TTL机制监控,完美匹配“标记删除后才开始计时”的需求。 - MongoDB的TTL后台任务默认每分钟执行一次,所以自动删除可能会有几分钟的延迟,属于正常机制。
- 给
trash字段加索引,能大幅提升前后端列表查询的性能。
内容的提问来源于stack exchange,提问作者Hunter
相关产品推荐
相关产品推荐

