JavaScript/JS백엔드
MongoDB 사용하기
염두리안
2025. 1. 1. 15:11
728x90
반응형
- 스키마 정의하기
- 스키마: 데이터의 틀
import mongoose from "mongoose";
const TaskSchema = new mongoose.Schema(
{
titile: {
type: String,
},
description: {
type: String,
},
siComplete: {
type: Boolean,
default: false,
},
},
{
// timestamps 사용시 mongo가 알아서 create, update app 필드를 생성&관리함
timestamps: true,
}
);
// 첫번째 아규먼트는 첫 글자를 대문자&단수형으로 씀
const Task = mongoose.model('Task', TaskSchema); // tasks 컬랙션에 데이터 추가, 조회, 삭제
export default Task;
- 시드 데이터 넣기
import mongoose from "mongoose";
import data from './mock.js';
import Task from '../models/Task.js';
import { DATABASE_URL } from "../env.js";
// 데이터베이스에 연결하는 코드
mongoose.connect(DATABASE_URL);
await Task.deleteMany({}); // 삭제 조건을 파라미터로 받음
await Task.insertMany(data); // 삽입할 데이터를 파라미터로 받음
mongoose.connection.close(); // 연결 종료
- 데이터 조회하기
- Model.find() 메소드에 필터 객체 전달시 조건을 만족하는 데이터만 조회 가능
- 비교연산자
- $gt : 특정 값을 초과하는지 확인 | Person.find({ age: { $gt: 35 } });
- $lt : 특정 값 미만인지 확인 | Person.find({ age: { $lt: 35 } });
- Regex 연산자: 문자열 필드가 특정 패턴을 가지고 있는지 확인
- $regex | Person.find({ email: { $regex: 'gmail\.com$' } });
- AND 연산자: 하나의 객체 안에 여러 조건 작성하면 됨
- Person.find({ age: { $lt: 32 }, email: { $regex: 'gmail\.com$' } });
- OR 연산자: $or
- Person.find({ $or: [{ age: { $lt: 32 } }, { email: { $regex: 'gmail\.com$' } }] });
- .findOne() : 다른 조건을 만족하는 객체 하나를 가져오고 싶을 때 사용... 조건을 만족하는 객체가 여러 개일 경우, 처음으로 매쳉된 객체 하나만 리턴
- Person.findOne({ name: 'James' });
- 모델 메소드 공식문서
- 쿼리 메소드 공식문서
// app.js에 있던 코드를
app.get('/tasks/:id', (req, res) => {
const id = Number(req.params.id);
const task = mocktasks.find((task) => task.id === id);
if (task){
res.send(task);
} else {
res.status(404).send({ message: `Can't find given id.` });
}
});
// 데이터베이스를 사용하도록 변경(쿼리를 리턴)
app.get('/tasks/:id', async (req, res) => {
const id = req.params.id;
const task = await Task.findById(id);
if (task){
res.send(task);
} else {
res.status(404).send({ message: `Can't find given id.` });
}
});
// app.get('/tasks') 함수를 다음과 같이 변경
app.get('/tasks', async (req, res) => {
const sort = req.query.sort;
const count = Number(req.query.count);
const sortOption = {
createdAt: sort === 'oldest' ? 'asc' : 'desc'
};
const tasks = await Task.find().sort(sortOption).limit(count); // 여러 객체를 가져옴
res.send(newTasks);
});
- 데이터 생성과 유효성 검사
- MongoDB에선 스키마를 통해 유효성 검사 가능
// [데이터생성] app.js 에 app.post를 다음과 같이 수정
app.post('/tasks', async (req, res) => {
const newTasks = await Task.create(req.body);
res.status(201).send(newTasks);
});
- 비동기 코드 오류 처리하기
function asyncHandler(handler) {
return async function (req, res) {
try{
await handler(req, res);
} catch (e) {
if (e.name === 'ValidationError') {
res.status(400).send({ message: e.message });
} else if (e.name === 'CastError') {
res.status(404).send({ message: 'Cannot find given id.'});
} else {
res.status(500).send( {message: e.message });
}
}
}
}
- 데이터 수정/삭제
// patch, delete 함수를 다음과 같이 수정
app.patch('/tasks/:id', async (req, res) => {
const id = req.params.id;
const task = await Task.findById(id);
if (task){
Object.keys(req.body).forEach((key) => {
task[key] = req.body[key];
});
await task.save();
res.send(task);
} else {
res.status(404).send({ message: `Can't find given id.` });
}
});
app.delete('/tasks/:id', asyncHandler(async (req, res) => {
const id = req.params.id;
const task = await Task.findByIdAndDelete(id);
if (task){
res.sendStatus(204);
} else {
res.status(404).send({ message: `Can't find given id.` });
}
}));
- MongoDB 접속시 Mongoose 라이브러리 사용
// DB접속
import mongoose from 'mongoose';
mongoose.connect('mongodb+srv://...');
// 스키마와 모델
import mongoose from 'mongoose';
const TaskSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
maxLength: 30,
},
description: {
type: String,
},
isComplete: {
type: Boolean,
required: true,
default: false,
},
},
{
timestamps: true,
}
);
const Task = mongoose.model('Task', TaskSchema);
export default Task;
// 유효성 검사를 원한다면...
{
title: {
type: String,
required: true,
maxLength: 30,
validate: {
validator: function (title) {
return title.split(' ').length > 1;
},
message: 'Must contain at least 2 words.',
},
},
// ...
}
- CRUD 연산
// 생성(create)
app.post('/tasks', async (req, res) => {
const newTask = await Task.create(req.body); // .create()로 객체 생성
res.status(201).send(newTask);
});
// 조회(read)
app.get('/tasks', async (req, res) => {
const tasks = await Task.find(); // 여러 객체 조회시 .find() 사용
res.send(tasks);
});
// id로 특정 객체 조회시 .findById() 사용
app.get('/tasks/:id', async (req, res) => {
const task = await Task.findById(req.params.id);
res.send(task);
} else {
res.status(404).send({ message: 'Cannot find given id.' });
}
});
// 정렬, 개수 제한
// find는 쿼리 리턴... 메소드 체이닝 가능
app.get('/tasks', async (req, res) => {
/** 쿼리 파라미터
* - sort: 'oldest'인 경우 오래된 태스크 기준, 나머지 경우 새로운 태스크 기준
* - count: 태스크 개수
*/
const sort = req.query.sort;
const count = Number(req.query.count) || 0;
const sortOption = { createdAt: sort === 'oldest' ? 'asc' : 'desc' };
const tasks = await Task.find().sort(sortOption).limit(count);
res.send(tasks);
})
);
// 수정(update)
app.patch('/tasks/:id', async (req, res) => {
const task = await Task.findById(req.params.id);
if (task) {
Object.keys(req.body).forEach((key) => {
task[key] = req.body[key];
});
await task.save();
res.send(task);
} else {
res.status(404).send({ message: 'Cannot find given id.' });
}
});
// 삭제(delete)
app.delete('/tasks/:id', async (req, res) => {
const task = await Task.findByIdAndDelete(req.params.id);
if (task) {
res.sendStatus(204);
} else {
res.status(404).send({ message: 'Cannot find given id.' });
}
});
- 비동기 오류
function asyncHandler(handler) {
return async function (req, res) {
try {
await handler(req, res);
} catch (e) {
// e.name(오류 이름), e.message(오류 메시지) 이용해서 오류 처리
}
};
}
// ...
app.get('/tasks', asyncHandler(async (req, res) => { ... }));
728x90
반응형