- vừa được xem lúc

Quản lý MongoDB với Mongoose trong NestJS

0 0 3

Người đăng: Dao Vinh Sơn

Theo Viblo Asia

MongoDB là một lựa chọn tuyệt vời khi bạn cần một cơ sở dữ liệu NoSQL linh hoạt, dễ mở rộng. Khi kết hợp với NestJS – một framework mạnh mẽ dựa trên Node.js và TypeScript – bạn sẽ có một bộ công cụ cực kỳ hiệu quả để phát triển các ứng dụng hiện đại.

Trong bài viết này, chúng ta sẽ cùng khám phá cách tích hợp Mongoose – thư viện ORM/ODM phổ biến nhất cho MongoDB – vào NestJS. Bạn sẽ được hướng dẫn từng bước từ cấu hình cơ bản đến triển khai các tính năng CRUD phức tạp.


Mục lục


1. Giới thiệu MongoDB và So sánh với SQL

MongoDB là gì?

MongoDB là một hệ quản trị cơ sở dữ liệu NoSQL mã nguồn mở, được thiết kế để lưu trữ dữ liệu dưới dạng document (tài liệu), sử dụng cấu trúc JSON/BSON thay vì các bảng quan hệ như trong MySQL hay PostgreSQL.

Dữ liệu trong MongoDB trông giống như thế này:

{ "title": "Giới thiệu MongoDB", "content": "MongoDB là một cơ sở dữ liệu NoSQL mạnh mẽ...", "tags": ["NoSQL", "MongoDB", "Database"], "author": { "name": "Nguyễn Văn A", "email": "a@example.com" }
}

Ưu điểm của MongoDB

  • Linh hoạt về cấu trúc dữ liệu: Không cần schema cố định, dễ thêm/xoá trường.
  • Dễ scale theo chiều ngang: Hỗ trợ sharding, thích hợp cho hệ thống phân tán.
  • Tốc độ cao với dữ liệu phi quan hệ: Rất hiệu quả khi làm việc với dữ liệu không cần liên kết chặt chẽ.

So sánh MongoDB với SQL

Tiêu chí MongoDB (NoSQL) SQL (MySQL, PostgreSQL,...)
Mô hình dữ liệu Document (BSON/JSON) Bảng (Table) với hàng và cột
Schema Không bắt buộc, linh hoạt Phải định nghĩa rõ ràng trước
Liên kết dữ liệu Thông qua embedded documents hoặc ObjectId Dùng foreign key để liên kết bảng
Truy vấn phức tạp Hạn chế hơn, dùng cú pháp JSON Hỗ trợ JOIN, GROUP BY, HAVING mạnh mẽ
Tính toàn vẹn dữ liệu Tùy thuộc vào ứng dụng quản lý Rất chặt chẽ nhờ constraints (PK, FK, v.v.)
Tốc độ truy xuất Nhanh với dữ liệu phi quan hệ, cache tốt Tốt với dữ liệu có quan hệ chặt chẽ
Scale Rất mạnh về horizontal scaling (sharding) Thường mạnh về vertical scaling

2. Giới thiệu về Mongoose và NestJS

  • NestJS là framework cho Node.js sử dụng TypeScript, cấu trúc theo kiến trúc module và DI (Dependency Injection) tương tự Angular.
  • Mongoose giúp bạn làm việc với MongoDB dễ dàng hơn bằng cách định nghĩa Schema, sử dụng Model, và thực hiện các thao tác với dữ liệu một cách trực quan, có kiểm soát.

3. Cài đặt NestJS và Mongoose

npm i -g @nestjs/cli
nest new nest-mongo-demo
cd nest-mongo-demo
npm install @nestjs/mongoose mongoose

Trong app.module.ts:

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose'; @Module({ imports: [ MongooseModule.forRoot('mongodb://localhost/nest-blog-demo', { useNewUrlParser: true, }), ],
})
export class AppModule {}

4. Tạo Schema và Model với Mongoose

Giả sử xây dựng API blog với model Post.

nest generate module posts
nest generate service posts
nest generate controller posts

Schema:

// posts/schemas/post.schema.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose'; export type PostDocument = Post & Document; @Schema({ timestamps: true })
export class Post { @Prop({ required: true }) title: string; @Prop() content: string; @Prop() author: string;
} export const PostSchema = SchemaFactory.createForClass(Post);

Module:

// posts/posts.module.ts
import { MongooseModule } from '@nestjs/mongoose';
import { Module } from '@nestjs/common';
import { PostsService } from './posts.service';
import { PostsController } from './posts.controller';
import { Post, PostSchema } from './schemas/post.schema'; @Module({ imports: [MongooseModule.forFeature([{ name: Post.name, schema: PostSchema }])], providers: [PostsService], controllers: [PostsController],
})
export class PostsModule {}

5. Tạo Service và Controller cho API

Service

@Injectable()
export class PostsService { constructor(@InjectModel(Post.name) private postModel: Model<PostDocument>) {} async findAll(): Promise<Post[]> { return this.postModel.find().exec(); } async create(data: Partial<Post>): Promise<Post> { const createdPost = new this.postModel(data); return createdPost.save(); } async findOne(id: string): Promise<Post> { return this.postModel.findById(id).exec(); } async update(id: string, data: Partial<Post>): Promise<Post> { return this.postModel.findByIdAndUpdate(id, data, { new: true }).exec(); } async remove(id: string): Promise<void> { await this.postModel.findByIdAndDelete(id).exec(); }
}

Controller

@Controller('posts')
export class PostsController { constructor(private readonly postsService: PostsService) {} @Get() findAll() { return this.postsService.findAll(); } @Post() create(@Body() data: Partial<Post>) { return this.postsService.create(data); } @Get(':id') findOne(@Param('id') id: string) { return this.postsService.findOne(id); } @Patch(':id') update(@Param('id') id: string, @Body() data: Partial<Post>) { return this.postsService.update(id, data); } @Delete(':id') remove(@Param('id') id: string) { return this.postsService.remove(id); }
}

6. Sử dụng DTO và Validation

npm install class-validator class-transformer

DTO:

export class CreatePostDto { @IsNotEmpty() @IsString() title: string; @IsString() content: string; @IsString() author: string;
}

Bật validation:

app.useGlobalPipes(new ValidationPipe());

7. Quan hệ giữa các collection (References)

Trong MongoDB, có thể tạo mối liên hệ giữa các collection qua ObjectIdpopulate.

@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User' })
author: User;
return this.postModel.find().populate('author').exec();

8. Middleware và Hooks trong Mongoose

PostSchema.pre('save', function (next) { console.log('Saving post:', this); next();
});

9. Tips và Best Practices

  • Luôn dùng DTO và ValidationPipe để lọc input.
  • Dùng .lean() nếu không cần full document.
  • Sử dụng indexes để tối ưu tìm kiếm.
  • Xem xét transaction nếu dùng nhiều model liên quan.

10. Kết luận

NestJS và Mongoose là một sự kết hợp lý tưởng để xây dựng các API hiện đại, dễ mở rộng và maintain. MongoDB với tính linh hoạt cao giúp bạn thoải mái phát triển mà không cần quá lo về schema cố định ban đầu.

Nếu bạn đang phát triển startup, MVP hoặc app có cấu trúc dữ liệu động – đây là lựa chọn rất đáng thử!

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cài đặt WSL / WSL2 trên Windows 10 để code như trên Ubuntu

Sau vài ba năm mình chuyển qua code trên Ubuntu thì thật không thể phủ nhận rằng mình đã yêu em nó. Cá nhân mình sử dụng Ubuntu để code web thì thật là tuyệt vời.

1 1 561

- vừa được xem lúc

Hướng dẫn làm bot Facebook messenger cho tài khoản cá nhân

Giới thiệu. Trong bài viết trước thì mình có hướng dẫn các bạn làm chatbot facebook messenger cho fanpage. Hôm nay mình sẽ hướng dẫn các bạn tạo chatbot cho một tài khoản facebook cá nhân. Chuẩn bị.

0 0 376

- vừa được xem lúc

Crawl website sử dụng Node.js và Puppeteer - phần 2

trong phần 1 mình đã giới thiệu về puppeteer và tạo được 1 project cùng một số file đầu tiên để các bạn có thể crawl dữ liệu từ một trang web bất kỳ. Bài này mình sẽ tiếp nối bài viết trước để hoàn thiện seri này.

0 0 79

- vừa được xem lúc

Điều React luôn giữ kín trong tim

■ Mở đầu. Ngồi viết bài khi đang nghĩ vu vơ chuyện con gà hay quả trứng có trước, mình phân vân chưa biết sẽ chọn chủ đề gì để chúng ta có thể cùng nhau bàn luận.

0 0 63

- vừa được xem lúc

Gửi Mail với Nodejs và AWS SES

AWS SES. AWS SES là gì.

0 0 89

- vừa được xem lúc

Crawl website sử dụng Node.js và Puppeteer - phần 1

Bài viết này mình sẽ giới thiệu cho các bạn craw dữ liệu của web site sử dụng nodejs và Puppeteer. .

0 0 168