2

I am learning NestJS, and Mongoose. I was wondering how to write down/code nested schemas in Mongoose using NextJS nomenclature.

Incoming data structure looks like this -

{
    something: {
        info: {
            title: string,
            score: number,
            description: string,
            time: string,
            DateOfCreation: string
        },
        Store: {
            item: {
                question: string,
                options: {
                    item: {
                        answer: string,
                        description: string,
                        id: string,
                        key: string,
                        option: string
                    }
                }
            }
        }
    }
}

Challenge: writing down that using NestJS internal APIs.

I am using NestJS and Mongoose. I want to write a schema for the data structure given above. I can't find examples for nested schemas. Any insigth is welcome.

I am a beginner in all NestJS, Mongoose and MongoDB. So please don't assume that I know something. Thus, any insight on Mongoose as well is welcome.

Thanks a lot.

Edit - Here's something I came up with after following this SO post - Mongoose Subdocuments in Nest.js . But I am just throwing stones in the dark.

import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";

@Schema()
export class Cat {
    @Prop()
    name: string
}


export const CatSchema = SchemaFactory.createForClass(Cat);


@Schema()
class testInfo {
    @Prop()
    title: string;
    @Prop()
    score: number;
    @Prop()
    description: string;
    @Prop()
    time: string;
    @Prop()
    DateOfCreation: string;
}

const testInfoSchema = SchemaFactory.createForClass(testInfo);

@Schema()
class OptionContent {
    @Prop()
    answer: string;
    @Prop()
    description: string;
    @Prop()
    id: string;
    @Prop()
    key: string;
    @Prop()
    option: string
}
const OptionContentSchema = SchemaFactory.createForClass(OptionContent);

@Schema({ strict: false })
class Option {
    @Prop({ type: OptionContentSchema })
    item: OptionContent;
}

const OptionSchema = SchemaFactory.createForClass(Option);

@Schema({ strict: false })
class Page {
    @Prop()
    question: string;
    @Prop({ type: OptionSchema })
    options: Option;
}

const PageSchema = SchemaFactory.createForClass(Page);

@Schema({ strict: false })
class McqStore {
    @Prop({ type: PageSchema })
    item: Page;
}

const McqStoreSchema = SchemaFactory.createForClass(McqStore);

@Schema()
export class Test {
    @Prop({ type: testInfoSchema })
    info: testInfo

    @Prop({ type: McqStoreSchema })
    McqStore: McqStore
}

const TestSchema = SchemaFactory.createForClass(Test);

@Schema()
export class TestContainer {
    @Prop({ type: TestSchema })
    name: Test
}

export const TestContainerSchema = SchemaFactory.createForClass(TestContainer);

export type userDocument = TestContainer & Document;
user3399180
  • 476
  • 2
  • 7
  • 18
  • Does this answer your question? [create object parent which nested children in mongoose](https://stackoverflow.com/questions/38820071/create-object-parent-which-nested-children-in-mongoose) – michaelgrigoryan25 Jun 05 '21 at 10:58
  • I am sorry it doesn't. Although it's possible to write things using mongoose in NestJS, I want to write the schema in NestJS way. I can't find any examples for that particular problem. – user3399180 Jun 05 '21 at 11:03

1 Answers1

4

nice question, it sparked my curiosity!

I am not new to Mongoose, but new to NestJS, learning to use. I was able to make this run properly.

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

export type CatDocument = Cat & Document;


@Schema()
export class Owners {
  @Prop()
  names: [string];
}

@Schema()
export class Cat {
  @Prop()
  name: string;

  @Prop()
  age: number;

  @Prop()
  breed: string;

  @Prop()
  owners: Owners;//schema for owner
}

export const CatSchema = SchemaFactory.createForClass(Cat);

Result! It seems to solve your problem, if I understand properly. Please, you need to adapt, and I am not sure about all this levels you added, you will have to experiment!

On your sample, you "compiled" the subschemas, if my memory serves me well, you do not do that even in Mongoose using express! I have to double check that! For NestJS, it seems, no need for that!

enter image description here

If you want something like: Mongoose Subdocuments in Nest.js, that is another story. My concern on this approach is using populate, I know how to use on Express, but no idea on NestJS.

I have found their documentation quite rich, and they have a repository as well. See here: https://docs.nestjs.com/techniques/mongodb

Update

user3399180 8 nicely sent me his final answer by e-mail!!

import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
import { Document } from "mongoose";

@Schema()
class testInfo {
    @Prop()
    title: string;
    @Prop()
    score: number;
    @Prop()
    description: string;
    @Prop()
    time: string;
    @Prop()
    dateOfCreation: string;
}

@Schema()
class OptionContent {
    @Prop()
    answer: string;
    @Prop()
    description: string;
    @Prop()
    id: string;
    @Prop()
    key: string;
    @Prop()
    option: string
}

@Schema()
class Option {
    @Prop()
    option: OptionContent;
}

@Schema()
class Page {
    @Prop()
    question: string;
    @Prop()
    options: Option;
}

@Schema()
class McqStore {
    @Prop()
    page: Page;
}

@Schema()
export class Test {
    @Prop()
    info: testInfo

    @Prop()
    McqStore: McqStore
}

@Schema()
export class TestContainer {
    @Prop({ type: Map })
    name: Test
}

export const TestContainerSchema = SchemaFactory.createForClass(TestContainer);

export type userDocument = Test & Document;

Related:

  1. NestJS - How to create nested schema with decorators
occasl
  • 5,303
  • 5
  • 56
  • 81
  • 1
    Perfect answer! Marking this as correct answer. – user3399180 Jun 06 '21 at 09:25
  • glad to help, it is pricely when we can help! – Jorge Guerra Pires Jun 06 '21 at 11:01
  • 1
    Hi! @Jorge Guerra Pires. Although your answer helped me a lot, I made some changes to fit the answer for my own needs. I am waiting this topic to open again so that I can post my code in the answers for future readers. – user3399180 Jun 06 '21 at 15:47
  • Glad I helped, I edited it, as so it can reopen. No idea if they will reopen. I am thinking to create a video on my channel, loved your question! Please, send me the final answer to jorgeguerrapires@yahoo.com.br – Jorge Guerra Pires Jun 06 '21 at 16:40
  • my channel: https://www.youtube.com/channel/UCFtxji3SCiowhynu_OVhcsA/videos – Jorge Guerra Pires Jun 06 '21 at 16:41
  • This solution creates an _id for the nested document. This is something I was trying to avoid while looking for an answer using mixed types (plain objects) in NestJS schemas. One way to avoid it is to add {_id: false} to the @Schema() decorator -> @Schema({_id: false}). That will avoid creating an _id only for the current level. Any additional nested schemas will generate an _id for their level. – Andi Aleksandrov Nov 12 '21 at 08:43