[MongoDB] Mongoose ODM, Mongoose 사용하기, Query, populate
글 작성자: 망고좋아
반응형
🎯 Mongoose ODM
- Object Data Modeling
- MongoDB의 Collection에 집중하여 관리하도록 도와주는 패키지
- Collection을 모델화하여, 관련 기능들을 쉽게 사용할 수 있도록 도와준다.
- 즉, 몽고디비의 컬렉션을 자바스크립트의 모델로 만들어 놓고 이 모델을 통해 몽고디비의 데이터에 접근하여 수정 및 삭제할 수 있게 도와주는 패키지이다.
📝 Mongoose ODM을 사용하는 이유
📕 연결 관리
- MongoDB의 기본 Node.js 드라이버는 연결 상태를 관리하기 어렵다.
- Mongoose를 사용하면 간단하게 데이터베이스와의 연결 상태를 관리해준다.
📕 스키마 관리
- 스키마를 정의하지 않고 데이터를 사용할 수 있는 것은 NoSQL의 장점이지만, 데이터 형식을 미리 정의해야 코드 작성과 프로젝트 관리에 유용하다.
- Mongoose는 Code-Level에서 스키마를 정의하고 관리할 수 있게 해 준다.
📕 Populate
- MongoDB는 기본적으로 Join을 제공하지 않는다.
- Join과 유사한 기능을 사용하기 위해선 aggregat라는 복잡한 쿼리를 해야 하지만, Mongoose는 populate를 사용하여 간단하게 구현할 수 있다.
📝 Mongoose ODM 사용 방법
📕 사용 순서
- 스키마 정의
- 모델 만들기
- 데이터베이스 연결
- 모델 사용
📕 스키마 정의하기
const { Schema } = require('mongoose'); // Schema 클래스 가져오기
const PostSchema = new Schema({
title: String,
content: String,
}, {
timestamps: true,
});
module.exports = PostSchema;
- Collection에 저장될 Document의 스키마를 Code-Level에서 관리할 수 있도록 Schema를 작성할 수 있다.
- Schema 란 데이터를 넣는 테이블이라고 이해하면 된다.
- 다양한 형식을 미리 지정하여, 생성, 수정 작업 시 데이터 형식을 체크해주는 기능을 제공한다.
- Mongoose는 Schema를 기준으로 데이터를 데이터베이스에 넣기 전에 검사를 하고 어긋나는 데이터들이 있으면 에러를 발생시킨다.
- timestamps 옵션을 사용하면 생성, 수정 시간을 자동으로 기록해준다.
📕 모델 만들기
const mongoose = require('mongoose');
const PostSchema = require('./schemas/board');
// model함수를 사용해서 Post라는 이름으로 PostSchema와 함께 전달해서 모델 생성
exports.Post = mongoose.model('Post', PostSchema);
- 작성된 스키마를 mongoose에서 사용할 수 있는 모델로 만들어야 한다.
- 모델의 이름을 지정하여 Populate 등에서 해당 이름으로 모델을 호출할 수 있다.
📕 데이터베이스 연결하기
const mongoose = require('mongoose');
const { Post } = require('./models'); // 작성된 Post 모델 load
mongoose.connect('mongodb://localhost:27017/myapp'); // DB에 연결
// Post 바로 사용 가능
connect
함수를 이용하여 간단하게 데이터베이스에 연결할 수 있다.- mongoose는 자동으로 연결을 관리하기 때문에 직접 연결 상태를 체크하지 않아도 모델 사용 시 연결 상태를 확인하여 사용이 가능할 때 작업을 실행한다.
📝 모델 사용하기 - 간단한 CRUD
CRUD | 함수명 |
CREATE | create |
READ | find, findById, findOne |
UPDATE | updateOne, updateMany, findByIdAndUpdate, findOneAndUpdate |
DELETE | deleteOne, deleteMany, findByIdAndDelete, findOneAndDelete |
- 작성된 모델을 이용하여 CRUD를 수행할 수 있다.
📕 CREATE
const { Post } = require("./models");
async function main() {
const created = await Post.create({
title: "first title",
content: "second title",
});
const multpleCreated = await Post.create([item1, item2]);
}
- create 함수를 사용하여 Document 생성할 수 있다.
- create 함수에는 Document Object나(단일 Document 생성) Document Object의 Array 전달(복수 Document 생성) 할 수 있다.
- create는 생성된 Document를 반환해준다.
📕 FIND (READ)
const { Post } = require("./models");
async function main() {
const listPost = await Post.find(query); // query
const onePost = await Post.findOne(query); // query
const postById = await Post.findById(id); // id
}
- find 관련 함수를 사용하여 Document를 검색할 수 있다.
query
를 사용하여 검색하거나findById
를 사용하면 ObjectID로 Document를 검색할 수 있다.- find는 배열 형식을 받아오고 findOne, findById는 하나의 Document를 받아온다.
📕 UPDATE
async function main() {
const updateResult = await Post.updateOne(query, {
...
});
const updateResults = await Post.updateMany(query, {
...
});
const postById = await Post.findByIdAndUpdate(id, {
...
});
const onePost = await Post.findOneAndUpdate(query, {
...
});
}
- update 관련 함수를 사용하여 Document를 수정
update~
관련 함수들은 update의 결과를 returnfind~
관련 함수들은 검색된 Document를 수정을 반영하여 반환해준다.- mongoose의 update는 기본적으로
$set
operator를 사용하기 때문에 Document를 통째로 변경하지 않는다. (MongoDB에서는 통째로 변경)
📕 DELETE
async function main() {
const deleteResult = await Post.deleteOne(query);
const deleteResults = await Post.deleteMany(query);
const onePost = await Post.findOneAndDelete(query);
const postById = await Post.findByIdAndDelete(query);
}
- delete 관련 함수를 사용하여 Document 삭제
- find~ 함수들은 검색된 Document를 반환해준다.
📝 Query
- MongoDB에도 SQL의 where와 유사한 조건절 사용할 수 있다.
- MongoDB의 query는 BSON 형식으로, 기본 문법 그대로 mongoose에서도 사용 가능하다.
📕 자주 사용되는 query
Person.find({
name: "kyubum",
age: {
$lt: 20,
$gte: 10,
},
languages: {
$in: ["ko", "en"],
},
$or: [{ status: "ACTIVE" }, { isFresh: true }],
});
- { key: value }로
exact match
$lt
,$lte
,$gt
,$gte
를 사용하여 range query 작성 가능$in
: 다중 값으로 검색, 배열에 주어진 값 중 최소 한 개의 일치하는 값을 가진 Document를 검색한다.$or
: 다중 조건 검색
📕 $in : 다중 값으로 검색
Person.find({ name: ["elice", "bob"] });
// { name: { $in: ['elice', 'bob'] } }
- Mongoose는 쿼리 값으로 배열이 주어지면 자동으로 $in 쿼리를 생성해 준다.
📝 populate
const Post = new Schema({
...
user: {
type: Schema.Types.ObjectId,
ref: "User",
},
comments: [
{
type: Schema.Types.ObjectId,
ref: "Comment",
},
],
});
//---------------------------------------
const post = await Post.find(query, {
populate: ["User", "Comment"],
});
// post.user.name, post.comments[0].content
// 다른 조건의 사용 예
const posts = await Post.find({}).populate('author'); // populate 사용하기
- JOIN과 유사한 기능을 제공해 준다.
- Document 안에 Document를 담지 않고, ObjectID를 가지고 reference 하여 사용할 수 있는 방법을 제공해주는 함수이다.
- aggregate 쿼리를 사용하지 않고, Document에는 reference 되는 ObjectID를 담고, 사용할 때 find 하여 하위 Document처럼 사용할 수 있게 해준다.
📝 Mongoose 쿼리 사용하기 예제 코드
- MongoDB에서 Document의 속성 유무를 체크하기 위해서는 $exists operator를 사용할 수 있다.
{ status: { $exists: false }, }
const mongoose = require('mongoose');
const { Post } = require('./models');
// 1. 몽고디비 연결
mongoose.connect("mongodb://localhost:27017/exam_5");
async function main() {
const posts = await Post.find({
// 쿼리 작성하기
// 2. 작성자는 "andy", "bob", "kate" 중에 한 명
author: [ "andy", "bob", "kate"], // === author: { $in: [ "andy", "bob", "kate"] }
// 3. 좋아요("likes") 수는 5개보다 크고, 10개보다 작거나 같습
likes: {
$gt: 5,
$lte: 10,
},
// 4. 게시글 분류("category")는 없거나 "notice" 입니다.
$or: [
{ category: { $exists: false} },
{ category: 'notice'}
]
});
return posts;
}
main()
.then((posts) => {
console.log("---검색 결과---");
console.log(posts);
console.log("---------------");
return;
})
.catch(err => {
console.error('에러가 발생했습니다.', err)
return;
})
.finally(() => {
process.exit();
});
const { Schema } = require('mongoose');
const PostSchema = new Schema({
title: {
type: String,
required: true,
},
author: {
type: String,
required: true,
},
content: {
type: String,
required: true,
},
likes: {
type: Number,
required: true,
default: 0
},
category: String
}, {
timestamps: true,
});
module.exports = PostSchema;
반응형
'프로그래밍 > DB' 카테고리의 다른 글
[mongoose] find에 대해서 알아보자 (0) | 2021.12.08 |
---|---|
[MongoDB] Express.js + Mongoose ODM 폴더 구조, 커넥션 이벤트 (0) | 2021.12.06 |
[MongoDB] MongoDB 기본 개념, 설치, 사용 방법 (0) | 2021.12.06 |
댓글
이 글 공유하기
다른 글
-
[mongoose] find에 대해서 알아보자
[mongoose] find에 대해서 알아보자
2021.12.08 -
[MongoDB] Express.js + Mongoose ODM 폴더 구조, 커넥션 이벤트
[MongoDB] Express.js + Mongoose ODM 폴더 구조, 커넥션 이벤트
2021.12.06 -
[MongoDB] MongoDB 기본 개념, 설치, 사용 방법
[MongoDB] MongoDB 기본 개념, 설치, 사용 방법
2021.12.06