개요
Mongoose 는 MongoDB 용 ODM(객체 데이터 모델링) 라이브러리입니다. Mongoose 사용하여 데이터 모델링, 스키마 시행, 모델 유효성 검사 및 일반적인 데이터 조작을 지원할 수 있습니다. MongoDB 향후 데이터베이스를 변경하고 업데이트 수 있는 유연한 데이터 모델을 제공하므로 엄격한 스키마가 없습니다. 그러나 Mongoose 처음부터 반강제 스키마 적용하므로 스키마 와 모델을 정의해야 합니다.
Schemas
스키마 컬렉션 문서의 구조를 정의합니다. Mongoose 스키마 MongoDB 컬렉션 에 직접 매핑됩니다.
다음 예시 blog
이라는 새 스키마를 만듭니다.
const blog = new Schema({ title: String, slug: String, published: Boolean, author: String, content: String, tags: [String], comments: [{ user: String, content: String, votes: Number }] }, { timestamps: true });
스키마 만들 때 각 필드 와 해당 데이터 유형을 정의해야 합니다. 허용되는 유형은 다음과 같습니다.
문자열
번호
날짜
Buffer
부울
혼합
ObjectId
배열
Int32
Decimal128
Double
Map
모델
모델은 스키마 가져와 컬렉션 의 각 문서 에 적용 . 모델은 생성, 읽기, 업데이트, 삭제 (CRUD ) 작업과 같은 모든 문서 상호 작용을 담당합니다.
팁
모델에 전달하는 첫 번째 인수는 컬렉션 이름의 단수형입니다. Mongoose 이 값을 자동으로 복수형으로 변경하고 소문자로 변환한 다음 이를 데이터베이스 컬렉션 이름으로 사용합니다.
다음 예시 blog
스키마 사용하는 Blog
이라는 모델을 선언하는 방법을 보여 줍니다.
const Blog = mongoose.model('Blog', blog);
앞의 예시 에서 Blog
은 MongoDB 에서 blogs
컬렉션 으로 변환됩니다.
튜토리얼
이 튜토리얼에서는 다음 작업을 수행합니다.
Mongoose 사용할 수 있는 환경 설정
MongoDB에 연결
Mongoose 스키마 및 모델 만들기
데이터 삽입, 업데이트, 찾기 및 삭제
문서 필드 프로젝트
데이터 유효성 검사
여러 스키마 및 미들웨어 사용
전제 조건 확인
이 튜토리얼을 시작하기 전에 다음 구성 요소가 준비되어 있는지 확인하십시오.
클러스터 구성된 MongoDB Atlas 계정. 지침을 보려면 Atlas 시작하기 가이드 참조하세요.
Node.js v16.20.1 또는 그 이후 버전.
환경 설정
이 튜토리얼에서는 nodemon을 사용하여 로컬에서 코드를 실행 . 터미널에서 다음 명령을 실행하여 프로젝트 초기화하고 필요한 종속성을 설치합니다.
mkdir mongodb-mongoose cd mongodb-mongoose npm init -y npm i mongoose npm i -D nodemon
선호하는 코드 편집기에서 프로젝트 엽니다. 이 튜토리얼에서는 CommonJS 대신 ES 모듈을 사용합니다. ES 모듈을 사용하려면 module
유형을 추가해야 합니다. package.json
파일 로 고 (Go) 다음 코드를 추가합니다.
... "scripts": { "dev": "nodemon index.js" }, "type": "module", ...
다음 명령을 실행 하여 nodemon
으로 애플리케이션 시작합니다.
npm run dev
참고
nodemon을 사용하면 파일 저장할 때마다 코드가 실행됩니다.
MongoDB에 연결
프로젝트 의 루트 수준에서 index.js
파일 만들고 파일 맨 위에 다음 코드를 추가합니다.
import mongoose from 'mongoose'; mongoose.connect("<connection string>")
<connection string>
자리 표시자를 MongoDB Atlas 연결 문자열 로 바꿉니다. 연결 문자열 찾는 방법에 대한 자세한 내용은 Atlas 설명서에서 Connect to Your Cluster(클러스터에 연결하기) 튜토리얼을 참조하세요.
스키마 및 모델 만들기
MongoDB 에서 데이터 추가 및 업데이트를 시작하기 전에 스키마 와 모델을 만들어야 합니다.
Mongoose 사용하면 필요한 각 스키마 에 대한 스키마 모델 파일 생성할 수 있습니다. 먼저 모든 스키마 파일을 넣을 model
폴더를 만든 다음 Blog.js
첫 번째 스키마 파일 만듭니다. 이 파일 열고 다음 코드를 추가합니다.
import mongoose from 'mongoose'; const { Schema, model } = mongoose; const blogSchema = new Schema({ title: String, slug: String, published: Boolean, author: String, content: String, tags: [String], comments: [{ user: String, content: String, votes: Number }] }, { timestamps: true }); const Blog = model('Blog', blogSchema); export default Blog;
이 스키마 자동으로 업데이트되는 스키마 에 mongoose-managed createdAt
및 updatedAt
필드를 추가하는 timestamps
옵션을 활성화합니다. 자세한 내용은 Mongoose 문서의 타임스탬프 페이지를 참조하세요.
CRUD 작업 수행하기
이제 첫 번째 모델과 스키마 설정하다 완료되었으며 데이터베이스 에 데이터 삽입을 시작할 수 있습니다. 다음 섹션에서는 Mongoose 사용하여 CRUD 작업을 수행하는 방법을 보여줍니다.
Insert Data
index.js
(으)로 고 (Go) 파일 맨 위에 다음 가져오기 성명서 추가합니다.
import Blog from './model/Blog.js';
연결 문자열 포함된 줄 아래에 다음 코드를 추가합니다.
// Creates a new blog post and inserts it into database const article = await Blog.create({ title: 'Awesome Post!', slug: 'awesome-post', published: true, content: 'This is the best post ever', tags: ['featured', 'announcement'], }); console.log('Created article:', article);
앞의 코드는 Mongoose create()
메서드를 사용하여 블로그 기사를 나타내는 객체 인스턴스화한 다음 데이터베이스 에 저장합니다. 반환된 문서 _id
를 포함하여 콘솔에 기록됩니다. 이후 단계에서 사용할 수 있도록 이 _id
를 기록해 둡니다.
데이터 업데이트
데이터를 업데이트 하려면 Mongoose 사용하여 로컬 객체 직접 편집할 수 있습니다. 그런 다음 save()
메서드를 사용하여 데이터베이스 에 업데이트 쓰기 (write) 수 있습니다.
다음 코드를 추가하여 이전 섹션에서 삽입한 아티클을 업데이트 .
// Updates the title of the article article.title = "The Most Awesomest Post!!"; await article.save(); console.log('Updated Article:', article);
Updated Article: { title: 'The Most Awesomest Post!!', slug: 'awesome-post', published: true, content: 'This is the best post ever', tags: [ 'featured', 'announcement' ], _id: new ObjectId('...'), comments: [], __v: 0 }
데이터 찾기
특정 문서 찾으려면 Mongoose findById()
메서드를 사용하여 문서 의 _id
을(를) 지정하여 문서를 쿼리 할 수 있습니다.
index.js
파일 에 다음 코드를 추가하여 _id
로 특정 기사를 찾습니다.
// Finds the article by its ID. Replace <object id> with the objectId of the article. const articleFound = await Blog.findById("<object id>").exec(); console.log('Found Article by ID:', articleFound);
Found Article by ID: { _id: new ObjectId('68261c9dae39e390341c367c'), title: 'The Most Awesomest Post!!', slug: 'awesome-post', published: true, content: 'This is the best post ever', tags: [ 'featured', 'announcement' ], comments: [], __v: 0 }
참고
기본값 으로 Mongoose 쿼리는 JavaScript Promise의 일부 속성을 가진 객체인 thenable을 반환합니다. 쿼리 에 exec()
메서드를 추가하여 실제 JavaScript Promise를 받을 수 있습니다. Mongoose 에서 프로미스 작업에 대해 자세히 학습하려면 Mongoose 문서의 프로미스 가이드 를 참조하세요.
문서 필드 지정
Mongoose 사용하여 필요한 필드만 프로젝트 할 수 있습니다. 다음 코드는 title
, slug
및 content
필드만 프로젝트 하도록 지정합니다.
index.js
파일 에 다음 코드를 추가하고 <object
id>
자리 표시자를 이전에 삽입한 문서 의 ObjectId
값으로 바꿉니다.
// Finds the article by its ID and projects only the title, slug, and content fields. // Replace <object id> with the objectId of the article. const articleProject = await Blog.findById("<object id>", "title slug content").exec(); console.log('Projected Article:', articleProject);
Projected Article: { _id: new ObjectId('...'), title: 'The Most Awesomest Post!!', slug: 'awesome-post', content: 'This is the best post ever' }
데이터 삭제
Mongoose deleteOne()
및 deleteMany()
메서드를 사용하여 컬렉션 에서 데이터를 삭제 . 삭제 하려는 문서 의 필드 지정하고 해당 필드 선택한 메서드에 전달할 수 있습니다.
데이터베이스 에서 하나의 아티클을 삭제 하려면 인덱스.js 파일 에 다음 코드를 추가하세요.
// Deletes one article with the slug "awesome-post". const blogOne = await Blog.deleteOne({ slug: "awesome-post" }); console.log('Deleted One Blog:', blogOne);
Deleted One Blog: { acknowledged: true, deletedCount: 1 }
여러 아티클을 삭제 하려면 다음 코드를 추가하면 됩니다.
// Deletes all articles with the slug "awesome-post". const blogMany = await Blog.deleteMany({ slug: "awesome-post" }); console.log('Deleted Many Blogs:', blogMany);
Deleted Many Blogs: { acknowledged: true, deletedCount: 4 }
데이터 유효성 검사
이전 단계에서 삽입된 아티클 스키마 author
, dates
또는 comments
필드가 포함되어 있더라도 포함되지 않습니다. 이는 문서 의 구조를 정의했지만 필수 필드를 정의하지 않았기 때문입니다. 필수로 정의되지 않은 필드 생략할 수 있습니다.
Mongoose 에서 필드 에 유효성 검사 포함하는 경우 객체 해당 값으로 전달해야 합니다.
참고
유효성 검사기는 create()
및 save()
메서드에서 자동으로 실행 . runValidators
옵션을 true
로 설정하여 update()
및 updateOne()
와 같은 업데이트 메서드에서 실행 지정할 수 있습니다. 유효성 검사기에 대한 자세한 내용은 Mongoose 설명서의 유효성 검사 페이지를 참조하세요.
Mongoose 에서는 여러 가지 유효성 검사 방법을 사용할 수 있습니다. 예시 를 들어, 요구하려는 모든 필드에 대해 required
를 true로 설정하다 수 있습니다. 유형과 서식의 유효성을 검사할 수도 있습니다. 다음 코드에서 slug
필드 4
의 minLength
이 있는 string
로 정의됩니다. 즉, 4 자 미만으로 slug
를 제공하면 ValidationError
이(가) 됩니다.
데이터 유효성 검사 추가하고 이러한 요구 사항을 정의하려면 다음 예시 와 같이 Blog.js
에서 스키마 업데이트 .
const blogSchema = new Schema({ title: { type: String, required: true, }, slug: { type: String, required: true, minLength: 4, }, published: { type: Boolean, default: false, }, author: { type: String, required: true, }, content: String, tags: [String], comments: [{ user: String, content: String, votes: Number }] }, { timestamps: true });
이 유효성 검사 추가하면 애플리케이션 충돌합니다. 새로운 유효성 검사 검사 요구 사항을 충족하려면 index.js
파일 의 create()
호출에 author
필드 추가합니다.
// Creates a new blog post and inserts it into database const article = await Blog.create({ title: 'Awesome Post!', slug: 'awesome-post', published: true, author: 'A.B. Cee', content: 'This is the best post ever', tags: ['featured', 'announcement'], });
팁
Mongoose 와 함께 스키마를 사용하는 경우 value: String
은 value: {type: String}
와 동일합니다.
자세한 내용은 Mongoose 설명서의 유효성 검사 페이지를 참조하세요.
여러 스키마 도입
다음으로, 다른 스키마 만들고 블로그 스키마 에 중첩하여 author
필드 에 더 많은 복잡성을 추가할 수 있습니다.
model
폴더에서 User.js
라는 새 파일 만듭니다. 이 파일 에 다음 코드를 추가합니다.
import mongoose from 'mongoose'; const {Schema, model} = mongoose; const userSchema = new Schema({ name: { type: String, required: true, }, email: { type: String, minLength: 10, required: true, lowercase: true }, }); const User = model('User', userSchema); export default User;
새 사용자 모델을 사용하여 블로그 스키마 에서 author
필드 정의하려면 Blog.js
파일 다음 변경 사항으로 업데이트 .
Mongoose 라이브러리에서 추출한 속성 목록에
SchemaTypes
를 추가합니다.author
필드type
를SchemaTypes.ObjectId
로 변경하고'User'
모델에 참조(ref
)를 추가합니다.
다음 코드는 이러한 업데이트를 보여줍니다.
const { Schema, SchemaTypes, model } = mongoose; ... // Inside Schema block: author: { type: SchemaTypes.ObjectId, ref: 'User', required: true, }, ...
blogSchema
정의를 변경하여 comment.user
필드 에 대해 동일한 User
모델을 재사용할 수 있습니다.
... // Inside Schema block: comments: [{ user: { type: SchemaTypes.ObjectId, ref: 'User', required: true, }, ...
애플리케이션 에서 새 사용자 모델을 사용하려면 index.js
파일 로 고 (Go) . 사용자 모델을 가져오려면 파일 맨 위에 다음 코드를 추가합니다.
import User from './model/User.js';
블로그 스키마 에 필드 유효성 검사 추가했기 때문에 블로그를 삽입, 업데이트 및 삭제 하고 프로젝트 에 필드를 지정하는 이전 코드는 유효성 검사 통과하지 못하고 애플리케이션 에 오류가 발생합니다.
다음 create()
호출을 추가하여 새 사용자를 만듭니다.
// Create a new user const user = await User.create({ name: 'Jess Garica', email: 'jgarcia@email.com', });
다음 코드에 표시된 대로 기존 create()
호출을 다음 코드로 업데이트하여 새 사용자를 작성자로 사용하는 새 아티클을 만듭니다.
// Creates a new blog post that references the user as the author const articleAuthor = await Blog.create({ title: 'Awesome Post!', slug: 'Awesome-Post', author: user._id, content: 'This is the best post ever', tags: ['featured', 'announcement'], }); console.log('Article with Author:', articleAuthor);
Article with Author: { title: 'Awesome Post!', slug: 'awesome-post', published: false, author: new ObjectId('...'), content: 'This is the best post ever', tags: [ 'featured', 'announcement' ], _id: new ObjectId('...'), createdAt: 2025-05-15T18:05:23.780Z, comments: [], __v: 0 }
앞의 코드는 MongoDB database 에 users
컬렉션 blogs
컬렉션 과 함께 추가합니다. 이 코드는 필수 author
필드 추가하고 해당 값을 user._id
로 설정합니다.
name
및 email
필드 값을 기사의 author
필드 에 추가하려면 블로그 쿼리 에 Mongoose populate()
메서드를 추가하면 됩니다. populate()
메서드는 user._id
가 참조하는 사용자 문서 에 대해 두 번째 쿼리 수행합니다.
다음 코드를 index.js
에 추가하여 이 데이터를 채웁니다.
// Populates the author field with user data const articlePopulate = await Blog.findOne({ title: "Awesome Post!" }).populate("author"); console.log('Article Populated:', articlePopulate);
Article Populated: { _id: new ObjectId('...'), title: 'Awesome Post!', slug: 'awesome-post', published: false, author: { _id: new ObjectId('...'), name: 'Jess Garica', email: 'jgarcia@email.com', __v: 0 }, content: 'This is the best post ever', tags: [ 'featured', 'announcement' ], createdAt: 2025-05-15T18:04:28.590Z, comments: [], __v: 0 }
자세한 내용은 Document.population() 을 참조하세요. Mongoose API 문서의 페이지입니다.
미들웨어 추가
Mongoose 에서 미들웨어는 스키마 수준에서 비동기 함수를 실행하기 전이나 실행하는 동안 실행 함수입니다.
미들웨어의 한 가지 예시 저장하거나 업데이트하기 전에 User
인스턴스 의 email
필드 의 유효성을 검사하는 함수입니다.
이 예시 validator
패키지 사용합니다. 다음 명령을 실행 하여 validator
패키지 설치할 수 있습니다.
npm install validator
이 미들웨어 함수를 추가하려면 User.js
파일 의 userSchema
선언에 다음 코드를 추가합니다.
import validator from 'validator';
userSchema.pre('save', function (next) { const user = this; // Normalize email if (user.email) { user.email = user.email.trim().toLowerCase(); } // Validate email format if (!validator.isEmail(user.email)) { return next(new Error('Invalid email format')); } next(); });
이 함수의 효과를 확인하려면 index.js
파일 의 user.email
필드 잘못된 이메일 주소 로 수정합니다.
const user = await User.create({ name: 'Jess Garica', email: 'jgarciaemail.com', });
Error: Invalid email format
이메일 주소 수정하면 오류가 발생하지 않는 것을 확인할 수 있습니다.
pre()
미들웨어 함수 외에도 Mongoose post()
미들웨어 함수도 제공합니다. 미들웨어에 대한 자세한 내용은 Mongoose 설명서의 미들웨어 페이지를 참조하세요.
다음 단계
이제 Mongoose 사용하여 MongoDB 컬렉션 에서 CRUD 작업을 수행하는 샘플 프로젝트 생겼습니다. 여기에서 이 프로젝트 를 기반으로 더 복잡한 쿼리 또는 문서 유효성 검사 빌드 하도록 선택할 수 있습니다. 다음 섹션에는 애플리케이션 에서 사용할 수 있는 Mongoose 기능의 몇 가지 예가 포함되어 있습니다.
Mongoose 사용자 지정 설정자
사용자 지정 설정자는 데이터가 저장될 때 데이터를 수정하며, 유효성 검사기와 유사하게 구현할 수 있습니다. Mongoose 다음과 같은 사용자 지정 설정자를 제공합니다.
lowercase
uppercase
trim
다음 예시 blog.slug
필드 의 문자를 소문자로 표시합니다.
const blogSchema = new Schema({ ... slug: { type: String, required: true, minLength: 4, lowercase: true, }, ... });
자세한 내용은 Mongoose API 설명서의 SchemaStringOptions 페이지를 참조하세요.
도우미 메서드
Mongoose 에는 일반 MongoDB 메서드에서 추상화된 여러 헬퍼 메서드가 포함되어 있습니다. 이 섹션에서는 이러한 메서드 중 일부의 예를 찾을 수 있습니다. 이러한 메서드는 이 튜토리얼에서 구체적으로 사용되지 않지만 Mongoose 시작할 때 참고하는 데 유용합니다.
exists()
exists()
메서드는 null
또는 제공된 쿼리 와 일치하는 첫 번째 문서 반환합니다. 다음은 author
필드 기준으로 아티클을 일치시키는 예시 입니다.
const blog = await Blog.exists({ author: 'Jess Garcia' }); console.log(blog);
자세한 내용은 Model.exists() 섹션을 API Mongoose .
where()
where()
메서드를 사용하면 복잡한 쿼리를 연결하고 빌드 수 있습니다.
다음은 일반 쿼리 객체 와 함께 findOne()
를 사용하고 where()
메서드로 이에 상응하는 쿼리 사용하여 찾기 작업을 수행하는 예시 입니다.
const blogFind = await Blog.findOne({ author: "Jess Garcia" }); console.log(blogFind); const blogWhere = await Blog.findOne().where("author").equals("Jess Garcia"); console.log(blogWhere);
이 구현 에서 where()
구현 findOne()
로 시작하여 Mongoose 이를 findOne()
쿼리 로 처리하도록 지시합니다. 이는 where()
을 단독으로 사용하는 경우(Blog.where(...)
) Mongoose 이를 암시적으로 find()
작업으로 처리하기 때문에 중요합니다.
일반적으로 where()
메서드는 동적 쿼리 작성 또는 여러 비교기가 포함된 복잡한 쿼리에 사용되거나 이 메서드를 사용하면 가독성이 향상됩니다. where()
메서드를 사용하는 것과 일반 객체 쿼리 사용하는 것 사이에는 성능 차이가 없습니다.
where()
메서드를 사용할 때 프로젝션 포함하려면 다음 예시 와 같이 쿼리 뒤에 select()
메서드를 연결합니다.
const blog = await Blog.findOne().where("author").equals("Jess Garcia").select("title author"); console.log(blog);
자세한 내용은 Mongoose API 문서의 다음 섹션을 참조하세요.
추가 리소스
MongoDB 와 함께 Mongoose 사용하는 방법에 대해 자세히 학습하려면 Mongoose 설명서를 참조하세요.
지원 찾거나 MongoDB Community 에 기여하려면 MongoDB 개발자 커뮤니티 페이지를 참조하세요.