> For the complete documentation index, see [llms.txt](https://jakekwak.gitbook.io/nestjs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jakekwak.gitbook.io/nestjs/recipes/untitled-1.md).

# MongoDB (Mongoose)

## MongoDB (Mongoose)

> **경고** 이 기사에서는 커스텀 컴포넌트를 사용하여 처음부터 *Mongoose\** 패키지를 기반으로 `DatabaseModule`을 작성하는 방법을 학습합니다. 결과적으로 이 솔루션에는 즉시 사용 가능한 전용 `@nestjs/mongoose` 패키지를 사용하여 생략할 수있는 많은 오버 헤드가 포함되어 있습니다. 자세한 내용은 [여기](https://app.gitbook.com/techniques/mongodb)를 참조하십시오.

[Mongoose](http://mongoosejs.com)은 가장 인기있는 [MongoDB](https://www.mongodb.org/) 객체 모델링 도구입니다.

## Getting started

이 라이브러리로 모험을 시작하려면 필요한 모든 종속성을 설치해야합니다.

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

가장 먼저해야 할 일은 `connect()`함수를 사용하여 데이터베이스와 연결하는 것입니다. `connect()`함수는 `Promise`를 반환하므로 [async provider](https://app.gitbook.com/fundamentals/async-components)를 만들어야 합니다.

```typescript
@@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` 접미사가 있는 별도의 파일로 사용자 지정 공급자를 선언했습니다.

그런 다음 응용 프로그램의 나머지 부분에 대해 액세스할 수 있도록 이러한 공급자를 내 보내야합니다.

```typescript
@@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를 사용하면 모든 것이 [스키마](http://mongoosejs.com/docs/guide.html)에서 파생됩니다. `CatSchema`를 정의 해 봅시다 :

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

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

`CatsSchema`는 `cats` 디렉토리에 속합니다. 이 디렉토리는 `CatsModule`을 나타냅니다.

이제 **모델** 공급자를 만들 차례입니다.

```typescript
@@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`에 삽입할 수 있습니다 :

```typescript
@@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`를 확장합니다:

```typescript
import { Document } from 'mongoose';

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

데이터베이스 연결은 **비동기**이지만 Nest는 최종 사용자가 이 프로세스를 완전히 볼 수 없도록합니다. `CatModel` 클래스는 db 연결을 기다리고 있으며 `CatsService`는 모델을 사용할 준비가 될 때까지 지연됩니다. 각 클래스가 인스턴스화 되면 전체 응용 프로그램을 시작할 수 있습니다.

마지막`CatsModule`은 다음과 같습니다.

```typescript
@@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`로 가져 오는 것을 잊지 마십시오.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jakekwak.gitbook.io/nestjs/recipes/untitled-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
