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)