MongoDB (Mongoose)

MongoDB (Mongoose)

๊ฒฝ๊ณ  ์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ์ปค์Šคํ…€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฒ˜์Œ๋ถ€ํ„ฐ Mongoose* ํŒจํ‚ค์ง€๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ DatabaseModule์„ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ด ์†”๋ฃจ์…˜์—๋Š” ์ฆ‰์‹œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ „์šฉ @nestjs/mongoose ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ๋žตํ•  ์ˆ˜์žˆ๋Š” ๋งŽ์€ ์˜ค๋ฒ„ ํ—ค๋“œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

Mongoose์€ ๊ฐ€์žฅ ์ธ๊ธฐ์žˆ๋Š” MongoDB ๊ฐ์ฒด ๋ชจ๋ธ๋ง ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

Getting started

์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋ชจํ—˜์„ ์‹œ์ž‘ํ•˜๋ ค๋ฉด ํ•„์š”ํ•œ ๋ชจ๋“  ์ข…์†์„ฑ์„ ์„ค์น˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

@@filename()
$ npm install --save mongoose
$ npm install --save-dev @types/mongoose
@@switch
$ npm install --save mongoose

๊ฐ€์žฅ ๋จผ์ €ํ•ด์•ผ ํ•  ์ผ์€ connect()ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. connect()ํ•จ์ˆ˜๋Š” Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ async provider๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@@filename(database.providers)
import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: (): Promise<typeof mongoose> =>
      mongoose.connect('mongodb://localhost/nest'),
  },
];
@@switch
import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: () => mongoose.connect('mongodb://localhost/nest'),
  },
];

info ํžŒํŠธ ๋ชจ๋ฒ” ์‚ฌ๋ก€์— ๋”ฐ๋ผ * .providers.ts ์ ‘๋ฏธ์‚ฌ๊ฐ€ ์žˆ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ์‚ฌ์šฉ์ž ์ง€์ • ๊ณต๊ธ‰์ž๋ฅผ ์„ ์–ธํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋„๋ก ์ด๋Ÿฌํ•œ ๊ณต๊ธ‰์ž๋ฅผ ๋‚ด ๋ณด๋‚ด์•ผํ•ฉ๋‹ˆ๋‹ค.

@@filename(database.module)
import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}

์ด์ œ @Inject() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Connection ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Connection ๋น„๋™๊ธฐ ๊ณต๊ธ‰์ž์— ์˜์กดํ•˜๋Š” ๊ฐ ํด๋ž˜์Šค๋Š” Promise๊ฐ€ ํ•ด๊ฒฐ ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

Model injection

Mongoose๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์Šคํ‚ค๋งˆ์—์„œ ํŒŒ์ƒ๋ฉ๋‹ˆ๋‹ค. CatSchema๋ฅผ ์ •์˜ ํ•ด ๋ด…์‹œ๋‹ค :

@@filename(schemas/cats.schema)
import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});

CatsSchema๋Š” cats ๋””๋ ‰ํ† ๋ฆฌ์— ์†ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋””๋ ‰ํ† ๋ฆฌ๋Š” CatsModule์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์ด์ œ ๋ชจ๋ธ ๊ณต๊ธ‰์ž๋ฅผ ๋งŒ๋“ค ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค.

@@filename(cats.providers)
import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
@@switch
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];

์•Œ๋ฆผ ์‹ค์ œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ๋งค์ง ๋ฌธ์ž์—ด์„ ํ”ผํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. CAT_MODEL๊ณผ DATABASE_CONNECTION์€ ๋ถ„๋ฆฌ ๋œ constants.ts ํŒŒ์ผ์— ๋ณด๊ด€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ @Inject() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ CAT_MODEL์„ CatsService์— ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค :

@@filename(cats.service)
import { Model } from 'mongoose';
import { Injectable, Inject } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CAT_MODEL')
    private readonly catModel: Model<Cat>,
  ) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return await this.catModel.find().exec();
  }
}
@@switch
import { Injectable, Dependencies } from '@nestjs/common';

@Injectable()
@Dependencies('CAT_MODEL')
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll() {
    return await this.catModel.find().exec();
  }
}

์œ„์˜ ์˜ˆ์—์„œ ์šฐ๋ฆฌ๋Š” Cat ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ชฝ๊ตฌ์Šค ํŒจํ‚ค์ง€์—์„œ Document๋ฅผ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค:

import { Document } from 'mongoose';

export interface Cat extends Document {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์€ ๋น„๋™๊ธฐ์ด์ง€๋งŒ Nest๋Š” ์ตœ์ข… ์‚ฌ์šฉ์ž๊ฐ€ ์ด ํ”„๋กœ์„ธ์Šค๋ฅผ ์™„์ „ํžˆ ๋ณผ ์ˆ˜ ์—†๋„๋กํ•ฉ๋‹ˆ๋‹ค. CatModel ํด๋ž˜์Šค๋Š” db ์—ฐ๊ฒฐ์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์œผ๋ฉฐ CatsService๋Š” ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•  ์ค€๋น„๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ์ง€์—ฐ๋ฉ๋‹ˆ๋‹ค. ๊ฐ ํด๋ž˜์Šค๊ฐ€ ์ธ์Šคํ„ด์Šคํ™” ๋˜๋ฉด ์ „์ฒด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰CatsModule์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@@filename(cats.module)
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}

warning ํžŒํŠธ CatsModule์„ ๋ฃจํŠธ ApplicationModule๋กœ ๊ฐ€์ ธ ์˜ค๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

Last updated

Was this helpful?