Schema는 자료의 구조를 의미한다. 그리고 그러한 구조는 Validation을 의미하기도 한다.
//Video Model
import mongoose from "mongoose"
//Video Data 구조.
const videoSchema = new mongoose.Schema({
title: { type: String, required: true, trim: true, maxLength: 80 },
description: { type:String, required: true, trim: true, minLength: 20 },
createdAt: { type:Date, required: true, default: Date.now },
hashtags: [{type: String, trim: true}],
meta: {
views: { type: Number, default: 0, required: true },
rating: { type: Number, default: 0, required: true },
},
});
//Middlware - hashtag의 #처리를 위한 formatHashtags 정의.
videoSchema.static("formatHashtags", function (hashtags){
return hashtags
.split(",")
.map((word) => (word.startsWith("#") ? word : `#${word}`)); // startsWith는 word의 제일 앞부분을 본다.
});
const Video = mongoose.model("Video", videoSchema);
export default Video;
//Read
export const watch = async (req, res) => {
const {id} = req.params;
// id로 해당하는 data를 DB에서 찾는다.
// Mongoose 지원 Model.findById
const video = await Video.findById(id);
if(!video){
return res.render("watch",{pageTitle: video.title, video});
}
return res.render("watch", {pageTitle: video.title, video});
};
//Update
//getEdit은 read와 다를바가없어 생략
export const postEdit = async (req, res) => {
const {id} = req.params;
const {title, description, hashtags} = req.body;
// true, false로 해당 결과값 가져오기.(DB내에 값이 존재하면 필터된 값을 반환 없다면 null 반환)
const video = await Video.exists({_id: id});
if(!video){
return res.render("404",{pageTitle: "Video not found."});
}
// 해당 id를 찾아 내용(title, description, hashtags) Update
// Mongoose 지원 Model.findByIdAndUpdate
await Video.findByIdAndUpdate(id, {
title,
description,
hashtags: Video.formatHashtags(hashtags),
});
return res.redirect(`/videos/${id}`);
};
//Create
export const postUpload = async (req, res) => {
const {title, description, hashtags} = req.body;
try{
console.log(title);
//Mongoose 지원 Model.create
await Video.create({
title,
description,
hashtags: Video.formatHashtags(hashtags),
});
return res.redirect("/");
}catch(error){
return res.render("upload",{
pageTitle:"Upload Video",
errorMessage: error._message,
});
}
}
//Delete
export const deleteVideo = async (req, res) => {
const {id} = req.params;
//Mongoose 지원 Model.findByIdAndDelete
await Video.findByIdAndDelete(id);
return res.redirect("/");
}
Javascript의 특성상 시간이 걸리는(DB조회 및 불러오기) 경우 그 뒤의 내용부터 실행되기 때문에 DB내용이 필요한 경우 async와 await를 사용.
export const search = async (req, res) =>{
const {keyword} = req.query;
let videos = [];
if(keyword){
videos = await Video.find({
title: {
// mongoDB 지원 Regular Expression
// i 는 대소문자 구분을 없애준다.(Welcome welcome)
$regex: new RegExp(keyword, "i"),
}
});
}
return res.render("search", {pageTitle: "Search", videos});
}
DB Connection
DB 전환 및 Collection(videos)으로 내용 검색