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 ?
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.
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.
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",
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).
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);
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With