DEV Community

Julie Cherner
Julie Cherner

Posted on

7 1 2

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.

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (1)

Collapse
 
mitinoh profile image
Mite

👋 Hi! Let me introduce Crudify, a library for NestJS that automatically generates CRUD endpoints with Mongoose. It's perfect for saving time and focusing on building amazing features. Check it out here: Crudify 🚀

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay