You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NestJs中使用Mongoose创建基于TTL的自销毁Schema

问题排查与修复方案

你的代码存在4个可导致TTL自销毁功能失效的问题,按优先级修正即可:

  • 拼写错误:导入的mangoose应为mongoose,拼写错误会导致类型引用、方法调用异常
  • 错误字段添加expires属性:Mongoose的TTL索引仅支持作用在Date类型字段上,你给number类型的OTP字段加expires: 3600属于无效配置,还可能干扰索引生成
  • expireAt默认值配置错误:当前写法Date.now() + 20000是在类定义阶段就执行计算,所有文档的过期时间都会被固定为项目启动时间+20秒,而非每条文档创建时动态计算的时间
  • 旧索引残留:修改Schema索引配置后,需要手动删除MongoDB对应集合里的旧TTL索引,否则新索引不会生效

正确实现代码

方案1:使用内置createdAt字段实现TTL(更简洁)

不需要额外定义过期字段,直接在Schema配置中开启timestamps并指定过期时间即可:

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import * as mongoose from 'mongoose';

export type OtpDocument = Otp & mongoose.Document;

@Schema({ timestamps: { createdAt: true }, expires: 20 }) // 文档创建后20秒自动删除
export class Otp {
  @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User' })
  user: mongoose.Types.ObjectId;

  @Prop()
  OTP: number;
}

export const OtpSchema = SchemaFactory.createForClass(Otp);

方案2:自定义expireAt字段控制过期时间

如果需要手动指定每条文档的过期时间,用该方案:

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import * as mongoose from 'mongoose';

export type OtpDocument = Otp & mongoose.Document;

@Schema()
export class Otp {
  @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User' })
  user: mongoose.Types.ObjectId;

  @Prop()
  OTP: number;

  @Prop({ default: () => new Date(Date.now() + 20000) }) // 传入函数,文档创建时动态计算过期时间
  expireAt: Date;
}

export const OtpSchema = SchemaFactory.createForClass(Otp);
OtpSchema.index({ expireAt: 1 }, { expireAfterSeconds: 0 });

生效注意事项

  • 修改索引配置后,先删除MongoDB对应集合中旧的TTL索引,再重启项目
  • MongoDB的TTL索引是后台轮询执行删除,默认每60秒扫描一次,所以删除操作最多有60秒的延迟,属于正常现象

内容的提问来源于stack exchange,提问作者Aniket

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 08:45:02