如何在Mongoose中实现created_at为毫秒数时的令牌自动过期删除?
问题原因
MongoDB 的 TTL 索引仅支持对 Date 类型的字段生效,你当前给 Number 类型的 created_at 配置 expires 属性,Mongoose 无法生成有效的TTL索引,所以自动删除功能不生效。
解决方案
由于你需要保留created_at为毫秒级Number类型的要求,我们可以新增一个专门用于TTL索引的Date类型字段即可,完全不影响原有业务逻辑,还能复用MongoDB原生的高效TTL自动删除能力。
修改后的完整代码如下:
const mongoose = require("mongoose"); const TokenSchema = new mongoose.Schema( { _id: mongoose.Schema.Types.ObjectId, token: String, deleted: Boolean, deleted_at: Number, // 保留原有毫秒级Number类型,移除无效的expires配置 created_at: { type: Number, default: Date.now }, // 新增专门用于TTL的Date类型字段,设置2分钟后过期 expire_at: { type: Date, expires: '2m', default: Date.now }, updated_at: Number, } ); TokenSchema.pre('save', function (next) { const now = Date.now(); this.updated_at = now; if (!this.created_at) { this.created_at = now; } next(); }); module.exports = mongoose.model('Token', TokenSchema);
注意事项
- 修改Schema后请先删除集合中已存在的无效旧索引,避免冲突。你可以在MongoDB shell中执行
db.tokens.dropIndex({created_at: 1})删除之前生成的无效索引 - 重启服务后可以执行
db.tokens.getIndexes()检查,确认存在expireAfterSeconds: 120的TTL索引即为配置生效 - MongoDB的TTL索引删除任务默认每分钟执行一次,所以令牌的实际删除时间可能存在最多1分钟的误差,属于正常情况
内容的提问来源于stack exchange,提问作者ololo
相关产品推荐
相关产品推荐

