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

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()手动声明字段,可以统一配置字段默认值和更新钩子:

  1. 字段定义时设置秒级默认值
@Prop({ default: () => Math.floor(Date.now() / 1000) })
CreatedAt: number;

@Prop({ default: () => Math.floor(Date.now() / 1000) })
UpdatedAt: number;
  1. 给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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 00:45:04