Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to populate mongoose references in nestjs?

I define a Person and Story schemas :

    @Schema()
    export class Person extends Document {
      @Prop()
      name: string;
    }
    export const PersonSchema = SchemaFactory.createForClass(Person);
    
    
    @Schema()
    export class Story extends Document {
    
      @Prop()
      title: string;
    
      @Prop()
      author:  { type: MongooseSchema.Types.ObjectId , ref: 'Person' }
    
    }
    export const StorySchema = SchemaFactory.createForClass(Story);

In my service I implemented save and read functions:

        async saveStory(){
        const newPerson = new this.personModel();
        newPerson.name  = 'Ian Fleming';
        await newPerson.save();
        const newStory  = new this.storyModel();
        newStory.title = 'Casino Royale';
        newStory.author = newPerson._id;
        await newStory.save();
      }
    
      async readStory(){
        const stories = await this.storyModel.
            findOne({ title: 'Casino Royale' })
        console.log('stories ',stories);
      }

When I ran readStory() I get the following output:

     stories  {
      _id: 5f135150e46fa5256a3a1339,
      title: 'Casino Royale',
      author: 5f135150e46fa5256a3a1338,
      __v: 0
    }

When I add a populate('author') to my query then I get author as null:

     stories  {
      _id: 5f135150e46fa5256a3a1339,
      title: 'Casino Royale',
      author: null,
      __v: 0
    }

How do I populate the author field with the referenced Person document ?

like image 329
Yaron Avatar asked Jul 18 '20 19:07

Yaron


People also ask

How to relate the entities in nestjs and mongoose?

Here is a little diagram with the schemas that describe the relations between the entities. NestJS and mongoose allow you to relate the entities, you can see in the code that for example we are referencing the User Schema on the Sales, Clients and Products to register the user that is creating each event.

How to implement put methods with MongoDB and mongoose?

There are quite a few ways of implementing a proper PUT method with MongoDB and Mongoose. The findByIdAndUpdate and findOneAndUpdate methods are common, but they don’t replace the whole document by default. Instead, they perform a partial update on it. Because of that, not including a property in the body of the request does not remove it.

What is the PUT method in nestjs?

The PUT method is responsible for modifying an existing entity. The crucial part about it is that it is supposed to replace an entity. Therefore, if we don’t send a field of an entity when performing a PUT request, the missing field should be removed from the document. "title": "API with NestJS #49. PUT vs PATCH with MongoDB and Mongoose",

What is nestjs?

MongoDB (Mongoose) | NestJS - A progressive Node.js framework Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reactive Programming).


2 Answers

After much reading and testing on mongoose references in nestjs. I think the accepted answer can be improved. I will show this in 2 steps. The first step is showing the declaration of MongooseSchema and including the comment of @illnr regarding the author property to use Types.ObjectId instead of MongooseSchema.Types.ObjectId.

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

@Schema()
export class Story extends Document {

  @Prop()
  title: string;

  @Prop({ type: MongooseSchema.Types.ObjectId , ref: 'Person' })
  author:  Types.ObjectId 

}

export const StorySchema = SchemaFactory.createForClass(Story);

And as a second step, I think it improves readability to use the Person class as type for the author property, as shown here.

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document, Types, Schema as MongooseSchema } from 'mongoose';
import { Person } from './person.schema'

@Schema()
export class Story extends Document {

  @Prop()
  title: string;

  @Prop({ type: MongooseSchema.Types.ObjectId , ref: 'Person' })
  author:  Person

}

export const StorySchema = SchemaFactory.createForClass(Story);
like image 134
Dick Bos Avatar answered Sep 20 '22 17:09

Dick Bos


Found it. My mistake was in defining the schema. Should be :

@Schema()
export class Story extends Document {
  @Prop()
  title: string;
    
  @Prop({ type: MongooseSchema.Types.ObjectId , ref: 'Person' })
  author:  MongooseSchema.Types.ObjectId  
}
like image 20
Yaron Avatar answered Sep 18 '22 17:09

Yaron