NestJS使用Mongoose时timestamps的updatedAt返回毫秒而非秒如何解决
问题根因
你在Schema类中通过@Prop()装饰器手动声明了CreatedAt、UpdatedAt字段,这一操作会覆盖@Schema装饰器中timestamps的自动字段配置,你自定义的currentTime函数不会作用到这两个手动声明的字段上,更新时默认使用mongoose内置的毫秒时间戳逻辑,就出现了不符合预期的情况。
修复方案
方案1(推荐):移除手动字段的@Prop装饰器
你已经在timestamps配置中指定了字段映射名称、时间生成规则,不需要额外手动定义字段规则。如果需要TypeScript类型提示,只保留字段类型声明即可,不要加@Prop()装饰器:
// 移除@Prop()装饰器,保留类型声明用于TS提示 CreatedAt: number; // 移除@Prop()装饰器,保留类型声明用于TS提示 UpdatedAt: number;
修改后timestamps的配置会自动生效,新增、更新操作都会调用你定义的currentTime函数生成秒级时间戳,不需要额外写钩子逻辑。
方案2:手动全链路配置时间规则
如果业务需要必须通过@Prop()手动声明字段,可以统一配置字段默认值和更新钩子:
- 字段定义时设置秒级默认值
@Prop({ default: () => Math.floor(Date.now() / 1000) }) CreatedAt: number; @Prop({ default: () => Math.floor(Date.now() / 1000) }) UpdatedAt: number;
- 给Schema新增更新前置钩子,自动更新秒级时间戳
import { SchemaFactory } from '@nestjs/mongoose'; // 你的Schema类定义 @Schema({ discriminatorKey: 'kind' }) export class YourModel { // ... 所有字段定义 } const schema = SchemaFactory.createForClass(YourModel); // 新增保存钩子 schema.pre('save', function (next) { this.UpdatedAt = Math.floor(Date.now() / 1000); next(); }); // 覆盖更新类操作的时间戳 schema.pre(['updateOne', 'findOneAndUpdate', 'updateMany'], function (next) { this.set({ UpdatedAt: Math.floor(Date.now() / 1000) }); next(); });
注意事项
检查你的更新操作代码,有没有手动传入timestamps: false参数,该参数会强制关闭时间戳自动生成逻辑,导致配置不生效。
内容的提问来源于stack exchange,提问作者Tri Nguyen
相关产品推荐
相关产品推荐

