References in not relational document databases may be implemented:
- Manually
- Using references
Example of manual implementation:
Model and scheme of user collection:
user.model.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';
import { BaseModel } from '../base/base.model';
import { Types } from 'mongoose';
export type UserDocument = HydratedDocument<UserModel>;
@Schema()
export class UserModel extends BaseModel {
@Prop()
username: string;
@Prop()
description: string;
@Prop()
password: string;
_id: Types.ObjectId
}
export const UserSchema = SchemaFactory.createForClass(UserModel);
_id of User may be manually saved in any other collection document (like Pos) and by getting this _id current user may be found in User collection with the additional query.
*But let’s avoid additional querying and use References to save and retrieve data.
*
Here post model is presented:
post.model.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';
import { BaseModel } from '../base/base.model';
import { Types } from 'mongoose';
export type PostDocument = HydratedDocument<PostModel>;
@Schema()
export class PostModel extends BaseModel {
@Prop()
name: string;
@Prop()
description: string;
@Prop({ type: Types.ObjectId, ref: 'UserModel' })
authorId: { type: Types.ObjectId; ref: 'UserModel' };
_id: Types.ObjectId;
}
export const PostSchema = SchemaFactory.createForClass(PostModel);
Type of User may be/better be added to authorId.
Here we sign the property for reference and put the model for reference.
At this point, reference is saved, let’s get the data!
Mongoose provides an alternative for MongoDB $lookup and it is populate method.
Let’s give arguments for this method (reference filed and selected field of the new object)
Service function:
async findOneAndPopulate(id: string, fieldName: string, chosenFields: Record<string, number>) {
return await this.baseModel
.findById(id)
.populate({ path: fieldName, select: chosenFields })
.exec();
}
Controller function:
@Get(':id')
findOne(@Param('id') id: string) {
return this.postService.findOneAndPopulate(id, 'authorId', {
username: 1,
});
}
Response results
Before ref and populate:
{
"_id": "6513ef6da50adaaa3d811721",
"name": "00000000000000000000000000",
"description": "tuyityityutyututuuutyutyutyutyutyuytutyutyuytutyutyutyutyutyutyutyutyutyuytutyutyutyutyu",
"authorId": "65082a6acd765074d09f38b0",
"__v": 0
}
After:
{
"_id": "6513ef6da50adaaa3d811721",
"name": "00000000000000000000000000",
"description": "tuyityityutyututuuutyutyutyutyutyuytutyutyuytutyutyutyutyutyutyutyutyutyuytutyutyutyutyu",
"authorId": {
"_id": "65082a6acd765074d09f38b0",
"username": "juliechernen@gmail.com"
},
"__v": 0
}
You are welcome to leave comments on other ways to use references in MongoDB and Mongoose.
Top comments (0)