Retseptlar3 min read

MongoDB (Mongoose)

Mongoose eng mashhur MongoDB obyekt modellashtirish vositasi.

Warning Ushbu maqolada siz Mongoose paketiga asoslangan DatabaseModule ni noldan, custom komponentlardan foydalanib qanday yaratishni o'rganasiz. Natijada, bu yechimda tayyor, qutidan tashqarida mavjud @nestjs/mongoose paketidan foydalanib chetlab o'tishingiz mumkin bo'lgan ko'p overhead mavjud. Batafsil bu yerda.

Mongoose eng mashhur MongoDB obyekt modellashtirish vositasi.

Boshlash

Ushbu kutubxona bilan ishni boshlash uchun barcha kerakli qaramliklarni o'rnatishimiz kerak:

TypeScript
1$ npm install --save mongoose

Birinchi qadam - connect() funksiyasi yordamida ma'lumotlar bazasi bilan ulanish o'rnatish. connect() funksiyasi Promise qaytaradi, shuning uchun async provider yaratishimiz kerak.

TypeScript
database.providers
1import * as mongoose from 'mongoose';
2
3export const databaseProviders = [
4  {
5    provide: 'DATABASE_CONNECTION',
6    useFactory: (): Promise<typeof mongoose> =>
7      mongoose.connect('mongodb://localhost/nest'),
8  },
9];
Hint

Eng yaxshi amaliyotlarga ko'ra, custom providerni *.providers.ts suffiksiga ega alohida faylda e'lon qildik.

Keyin, ilovaning qolgan qismi uchun ularni mavjud qilish uchun bu providerlarni eksport qilishimiz kerak.

TypeScript
database.module
1import { Module } from '@nestjs/common';
2import { databaseProviders } from './database.providers';
3
4@Module({
5  providers: [...databaseProviders],
6  exports: [...databaseProviders],
7})
8export class DatabaseModule {}

Endi Connection obyektini @Inject() dekoratori yordamida inject qila olamiz. Connection async provideriga bog'liq har bir klass Promise bajarilguncha kutadi.

Modelni inject qilish

Mongoose bilan hamma narsa Schema dan kelib chiqadi. CatSchema ni aniqlaymiz:

TypeScript
schemas/cat.schema
1import * as mongoose from 'mongoose';
2
3export const CatSchema = new mongoose.Schema({
4  name: String,
5  age: Number,
6  breed: String,
7});

CatsSchema cats katalogiga tegishli. Bu katalog CatsModule ni ifodalaydi.

Endi Model provider yaratish vaqti keldi:

TypeScript
cats.providers
1import { Connection } from 'mongoose';
2import { CatSchema } from './schemas/cat.schema';
3
4export const catsProviders = [
5  {
6    provide: 'CAT_MODEL',
7    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
8    inject: ['DATABASE_CONNECTION'],
9  },
10];
Warning

Amaliy ilovalarda magic string lardan qochish kerak. CAT_MODEL va DATABASE_CONNECTION har ikkalasi alohida constants.ts faylida saqlanishi kerak.

Endi CAT_MODEL ni CatsService ga @Inject() dekoratori yordamida inject qila olamiz:

TypeScript
cats.service
1import { Model } from 'mongoose';
2import { Injectable, Inject } from '@nestjs/common';
3import { Cat } from './interfaces/cat.interface';
4import { CreateCatDto } from './dto/create-cat.dto';
5
6@Injectable()
7export class CatsService {
8  constructor(
9    @Inject('CAT_MODEL')
10    private catModel: Model<Cat>,
11  ) {}
12
13  async create(createCatDto: CreateCatDto): Promise<Cat> {
14    const createdCat = new this.catModel(createCatDto);
15    return createdCat.save();
16  }
17
18  async findAll(): Promise<Cat[]> {
19    return this.catModel.find().exec();
20  }
21}

Yuqoridagi misolda Cat interfeysidan foydalandik. Bu interfeys mongoose paketidagi Document dan meros oladi:

TypeScript
1import { Document } from 'mongoose';
2
3export interface Cat extends Document {
4  readonly name: string;
5  readonly age: number;
6  readonly breed: string;
7}

Ma'lumotlar bazasi ulanishi asinxron, lekin Nest bu jarayonni oxirgi foydalanuvchi uchun butunlay ko'rinmas qiladi. CatModel klassi db ulanishini kutadi, CatsService esa model tayyor bo'lguncha kechiktiriladi. Har bir klass nusxasi yaratilgach butun ilova ishga tushishi mumkin.

Mana yakuniy CatsModule:

TypeScript
cats.module
1import { Module } from '@nestjs/common';
2import { CatsController } from './cats.controller';
3import { CatsService } from './cats.service';
4import { catsProviders } from './cats.providers';
5import { DatabaseModule } from '../database/database.module';
6
7@Module({
8  imports: [DatabaseModule],
9  controllers: [CatsController],
10  providers: [
11    CatsService,
12    ...catsProviders,
13  ],
14})
15export class CatsModule {}
Hint

CatsModule ni ildiz AppModule ga import qilishni unutmang.

Misol

Ishlaydigan misol bu yerda mavjud.