Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NestJS MongoDB nested object schema

I am currently running the code :

export class SystemInformationContent {
  createdAt: number;

  createdBy: User | mongoose.Schema.Types.ObjectId | null;

  updatedAt?: number;

  updatedBy?: User | mongoose.Schema.Types.ObjectId | null;
}

@Schema()
export class SystemInformation {
  @Prop(
    raw({
      createdAt: { type: Number, required: true },
      createdBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
      updatedAt: { type: Number, default: 0 },
      updatedBy: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        default: null,
      },
    }),
  )
  system: SystemInformationContent;
}

I did not found any way of "extending" the schema of SystemInformationContent and so used the raw() function in the @Prop() decorator, but I am wondering if there is a way to do something like this:

export class SystemInformationContent {
  @Prop({ required: true })
  createdAt: number;

  @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User' })
  createdBy: User | mongoose.Schema.Types.ObjectId | null;

  @Prop({ default: 0 })
  updatedAt?: number;

  @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User', default: null })
  updatedBy?: User | mongoose.Schema.Types.ObjectId | null;
}

@Schema()
export class SystemInformation {
  @Prop(???)
  system: SystemInformationContent;
}

I did not found anything working to put into the SystemInformation.system @Prop() that take in account the schema of SystemInformationContent.

Do you guys know if there is an other way than the raw or if I am missing something ?

Edit: All classes of my NestJS application are extending SystemInformation so they all look like :

{
  ...,
  system: {
    createdAt: 1616778310610,
    createdBy: "605e14469d860eb1f0641cad",
    editedAt: 0,
    createdBy: null,
  },
}
like image 380
Falcort Avatar asked May 23 '26 09:05

Falcort


1 Answers

Found a solution !

I edited SystemInformationContent to :

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import * as mongoose from 'mongoose';
import { User } from '~/schemas/user.schema';

@Schema({ _id: false })
export class SystemInformationContent {
  @Prop({ type: Number, required: true })
  createdAt: number;

  @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User' })
  createdBy: User;

  @Prop({ type: Number, default: 0 })
  updatedAt?: number;

  @Prop({
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    default: null,
  })
  updatedBy?: User;
}

export const SystemInformationContentSchema = SchemaFactory.createForClass(
  SystemInformationContent,
);

Then in SystemInformation I edited to :

import { Prop, Schema } from '@nestjs/mongoose';
import {
  SystemInformationContent,
  SystemInformationContentSchema,
} from '~/schemas/systemInformationContent.schema';

@Schema()
export default class SystemInformation {
  @Prop({ required: true, type: SystemInformationContentSchema })
  system: SystemInformationContent;
}

Now everything is working, I used the @Schema({ _id: false }) to remove the ID generated by the SchemaFactory so I end up with that in the DB :

{
  ...,
  "system": {
    "updatedBy": null,
    "updatedAt": 0,
    "createdAt": 1616847116986,
    "createdBy": {
      "$oid": "605f210cc9fe3bcbdf01c95d"
    }
  },
  ...,
}
like image 88
Falcort Avatar answered May 25 '26 11:05

Falcort



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!