DEV Community

Julie Cherner
Julie Cherner

Posted on

Quick start with MongoDB references | Mongoose, Nest.js + Examples

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);

Enter fullscreen mode Exit fullscreen mode

_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);

Enter fullscreen mode Exit fullscreen mode

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();
}

Enter fullscreen mode Exit fullscreen mode

Controller function:

@Get(':id')
findOne(@Param('id') id: string) {
return this.postService.findOneAndPopulate(id, 'authorId', {
username: 1,
});
}

Enter fullscreen mode Exit fullscreen mode

Response results

Before ref and populate:

{
    "_id": "6513ef6da50adaaa3d811721",
    "name": "00000000000000000000000000",
    "description": "tuyityityutyututuuutyutyutyutyutyuytutyutyuytutyutyutyutyutyutyutyutyutyuytutyutyutyutyu",
    "authorId": "65082a6acd765074d09f38b0",
    "__v": 0
}

Enter fullscreen mode Exit fullscreen mode

After:

{
    "_id": "6513ef6da50adaaa3d811721",
    "name": "00000000000000000000000000",
    "description": "tuyityityutyututuuutyutyutyutyutyuytutyutyuytutyutyutyutyutyutyutyutyutyuytutyutyutyutyu",
    "authorId": {
        "_id": "65082a6acd765074d09f38b0",
        "username": "juliechernen@gmail.com"
    },
    "__v": 0
}

Enter fullscreen mode Exit fullscreen mode

You are welcome to leave comments on other ways to use references in MongoDB and Mongoose.

Top comments (0)