MongoDB实现trash设为true的文档一个月后自动删除
方案一:利用MongoDB TTL索引自动删除
这是最省心的实现方式,依托MongoDB原生的TTL(自动过期)功能,无需额外编写定时逻辑。
- 修改Schema结构
新增deletedAt字段记录文档被标记为删除的时间,同时给该字段添加TTL索引,设置30天(2592000秒)的过期时长:
const product = new Schema({ name: String, trash: { type: Boolean, default: false }, deletedAt: Date // 新增字段,存储标记删除的时间 }, { timestamps: true }); // 给deletedAt添加TTL索引,30天后自动删除文档 product.index({ deletedAt: 1 }, { expireAfterSeconds: 30 * 24 * 60 * 60 });
- 更新标记删除的代码
标记文档为删除时,同步设置deletedAt为当前时间:
const task = { $set: { trash: true, deletedAt: new Date() // 记录标记删除的时间点 } }; const removeDoc = await Product.findOneAndUpdate(query, task, { new: true });
设置完成后,MongoDB会自动检测deletedAt字段,当时间超过30天时自动删除对应文档。
方案二:用定时任务批量清理(适合自定义逻辑场景)
如果需要在删除前执行额外操作(比如清理关联数据、发送通知),或者不想依赖MongoDB的TTL机制,可以用Node.js定时任务库实现定期清理。
- 安装依赖
npm install node-schedule
- 编写定时任务
示例为每天凌晨1点执行一次清理,删除trash为true且deletedAt超过30天的文档:
const schedule = require('node-schedule'); // 定时任务:每天凌晨1点执行 schedule.scheduleJob('0 0 1 * * *', async () => { try { // 计算30天前的时间戳 const thirtyDaysAgo = new Date(); thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30); // 批量删除符合条件的文档 const result = await Product.deleteMany({ trash: true, deletedAt: { $lte: thirtyDaysAgo } }); console.log(`清理完成,共删除${result.deletedCount}条过期文档`); } catch (err) { console.error('清理过期文档失败:', err); } });
注:此方案同样需要先在Schema中新增deletedAt字段,并在标记删除时设置该字段的值(和方案一的步骤1、2一致)。
提醒:
- TTL索引要求
deletedAt必须是Date类型,若文档无该字段则不会被自动删除; - 定时任务的时间表达式可按需调整,比如
'0 */6 * * *'代表每6小时执行一次。
内容的提问来源于stack exchange,提问作者Hunter
相关产品推荐
相关产品推荐

