如何用Mongoose实现文档自动删除?测试TTL过期无效,需设10天过期
解决Mongoose TTL自动删除文档失效的问题
问题分析
你的TTL自动删除失效主要源于几个关键点:
- Schema中
expires参数设置错误(测试时写了5000秒而非预期的5秒) - 手动指定
expires_at日期时,与Schema中的expires数字值产生逻辑冲突 - 可能未正确创建TTL索引,或未触发MongoDB的TTL清理机制
解决方案
1. 修正Schema配置
根据你手动指定10天后过期的需求,调整Schema如下:
const ShortUrlModel = mongoose.model( 'ShortUrl', new mongoose.Schema({ original_url: String, hash: String, expires_at: { type: Date, expires: 0 // 表示文档在expires_at指定的时间点立即过期 }, }), );
也可以通过手动创建TTL索引的方式实现:
const ShortUrlSchema = new mongoose.Schema({ original_url: String, hash: String, expires_at: Date, }); // 显式创建TTL索引,指定在expires_at时间到达时删除文档 ShortUrlSchema.index({ expires_at: 1 }, { expireAfterSeconds: 0 }); const ShortUrlModel = mongoose.model('ShortUrl', ShortUrlSchema);
2. 验证并修复TTL索引
打开MongoDB Shell,执行以下命令检查集合索引(集合名为模型名的小写复数,即shorturls):
db.shorturls.getIndexes()
需确认存在包含expires_at:1的索引,且expireAfterSeconds值为0。
若旧索引配置错误,先删除旧索引:
db.shorturls.dropIndex('expires_at_1')
重启服务后,Mongoose会自动创建新的正确索引。
3. 确认过期时间计算逻辑
你接口中计算10天后过期的逻辑是正确的,可简化为:
const expires_at = new Date(); expires_at.setDate(expires_at.getDate() + 10);
4. 注意MongoDB TTL的清理周期
MongoDB的TTL清理任务默认每分钟运行一次,即使文档到了过期时间,也需要等待最多1分钟才会被删除,测试时不要立刻判定功能失效。
额外优化方案
如果无需手动计算过期时间,可让Mongoose自动生成过期时间:
const ShortUrlModel = mongoose.model( 'ShortUrl', new mongoose.Schema({ original_url: String, hash: String, expires_at: { type: Date, default: () => Date.now() + 10 * 24 * 60 * 60 * 1000, // 自动设置为创建时间+10天 expires: 0 }, }), );
这种情况下,接口代码中无需手动设置expires_at字段。
内容的提问来源于stack exchange,提问作者Michael-Liendo
相关产品推荐
相关产品推荐

