NestJs Nested Document In MongoDB with schema
NestJS插入数据到Mongodb中,嵌入子对象的Date类型数据不正确,变成字符串而不是Date对象?
如果在MongoCompass中看到的是红叉类似的数据,说明日期是被作为字符串存储了,如果是绿勾处的数据格式,则说明是按ISODate数据存储的。
insert nested document in mongoose(Date field not work):
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");
}
如果嵌入对象也有嵌入对象,照此类推办理即可。