首页  编辑  

Mongodb schema定义中嵌入对象时指定schema

Tags: /Node & JS/   Date Created:

NestJs Nested Document In MongoDB with schema

NestJS插入数据到Mongodb中,嵌入子对象的Date类型数据不正确,变成字符串而不是Date对象?
如果在MongoCompass中看到的是红叉类似的数据,说明日期是被作为字符串存储了,如果是绿勾处的数据格式,则说明是按ISODate数据存储的。

insert nested document in mongoose(Date field not work):
NestJs Nested Document In MongoDB | by Yadollah khaje hosseini | Medium

Mongodb,Typescript,NestJS定义Schema的时候,如果要嵌入子对象,例如:
@Schema()
export class Demo {
  @Prop()
  refNo: string;
  @Prog()
  name: string;
  @Prop()
  list: Array<SubInfo>;
  @Prop({default: () => new Date() })
  createdTime: Date;
}
export type DemoDocument = Demo & Document;

export class SubInfo extends Document {
  @Prop()
  code: string;
  @Prop()
  address: string;
  @Prop()
  start: Date;
  @Prop()
  end: Date;
}
DTO类定义类似,在此略。当按上述方式保存到Mongodb数据库之后,嵌入对象的start, end 这两个日期,保存的数据会变成字符串类型,例如下面数据的下划线部分,而没有嵌套的部分如绿色高亮部分却是正确的数据类型:
{
  "refNo": "1234",
  "name": "Bill",
  "SubInfo" : [ 
    {
      "code" : "1",
      "address": "xxx",
      "start" : "2024-01-03T14:10:00.000+08:00",
      "end" : "2024-01-04T14:10:00.000+08:00",
    }, 
    {
      "code" : "2",
      "address": "yyy",
      "start" : "2024-01-03T14:10:00.000+08:00",
      "end" : "2024-01-04T14:10:00.000+08:00",
    }
  ],
  createdTime: ISODate("2024-01-04T14:10:00.000+08:00");
}
为了让嵌入对象也能变成正确的数据类型,例如 Date 类型,需要修改如下:
  • 必须把嵌入对象单独定义一个 schema.ts 文件
  • 在单独 schema 类定义文件中, export const SubInfoSchema = SchemaFactory.createForClass(SubInfo);
  • 在类嵌入对象定义的时候,@Prop 注解中,显式指定 type: Schema
例如,上述示例代码,正确实现为:
Demo.schema.ts类:
@Schema()
export class Demo {
  @Prop()
  refNo: string;
  @Prog()
  name: string;
  @Prop([{type: SubInfoSchema}])
  list: Array<SubInfo>;
  @Prop({default: () => new Date() })
  createdTime: Date;
}
export type DemoDocument = Demo & Document;
SubInfo.schema.ts 类:
export type SubInfoDocument = SubInfo & Document;
@Schema({
  _id: false,
  timestamps: false,
  versionKey: false,
  strict: true,
  toJSON: {
    virtuals: true,
    transform: function (doc, ret) {
      delete ret._id;
    },
  },
})
export class SubInfo extends Document {
  @Prop()
  code: string;
  @Prop()
  address: string;
  @Prop()
  start: Date;
  @Prop()
  end: Date;
}

export const SubInfoSchema = SchemaFactory.createForClass(SubInfo);
此后,保存到Mongodb数据库,嵌入对象数据类型即正确:
{
  "refNo": "1234",
  "name": "Bill",
  "SubInfo" : [ 
    {
      "code" : "1",
      "address": "xxx",
      "start" : ISODate("2024-01-03T14:10:00.000+08:00"),
      "end" : ISODate("2024-01-04T14:10:00.000+08:00"),
    }, 
    {
      "code" : "2",
      "address": "yyy",
      "start" : ISODate("2024-01-03T14:10:00.000+08:00"),
      "end" : ISODate("2024-01-04T14:10:00.000+08:00"),
    }
  ],
  createdTime: ISODate("2024-01-04T14:10:00.000+08:00");
}
如果嵌入对象也有嵌入对象,照此类推办理即可。