Mongo(terminal)
mongo
show dbs
db
use dbName
(현재 수업에서는 use wetube
)
show collections
db.collectionName.find()
(현재 수업에서는 db.videos.find()
)
db.collectionName.remove({})
(현재 수업에서는 db.videos.remove({})
)
사용하기
npm i mongoose
db.js 파일 만들고 밑의 코드는 db.js의 내용
import mongoose from "mongoose";
mongoose.connect("mongodb://127.0.0.1:27017/databaseName", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const db = mongoose.connection;
const handleOpen = () => console.log("✅ Connect to DB");
const handleError = (error) => console.log("DB Error", error);
db.on("error", handleError);
db.once("open",handleOpen);
mongoose가 제대로 연결됐으면 handleOpen 제대로 연결 안됐으면 handleError
server.js 에 db.js 파일 전체 import하기
Schema 생성
import mongoose from "mongoose";
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,},
},
});
const Video = mongoose.model("Video", videoSchema);
export default Video;
MongoDB는 스키마가 없지만 Mongoose에서는 Schema를 정의해줄 수 있다.
모델 생성
const Video = mongoose.model("Video", videoSchema);
export default Video;
만든 Model server.js에 import하기
callback과 async/await
export const home = (req, res) => {
Video.find({}, (error, videos) => {
res.render("home", { pageTitle: "Home", videos });
});
}
export const home = async(req, res) => {
const videos = await Video.find({});
res.render("home", { pageTitle: "Home", videos });
}
CRUD
CREATE
const {title, description, hashtags} = req.body;
const video = new Video({
title,
description,
hashtags: hashtags.split(",").map(word => `#${word}`),
createdAt: Date.now(),
meta: {
views: 0,
rating: 0
}
});
await video.save()
const {title, description, hashtags} = req.body;
await Video.create({
title,
description,
hashtags: hashtags.split(",").map(word => `#${word}`),
createdAt: Date.now(),
meta: {
views: 0,
rating: 0
}
});
const {title, description, hashtags} = req.body;
try{
await Video.create({
title,
description,
hashtags: hashtags.split(",").map(word => `#${word}`),
// createdAt: Date.now(),
});
return res.redirect("/");
} catch(error) {
return res.render("upload",{
pageTitle : `Upload Video`,
errorMessage: error._message
});
}
READ
export const watch = async(req, res) => {
const { id } = req.params;
const video = await Video.findById(id);
console.log(video);
return res.render("watch", { pageTitle: video.title, video });
}
export const watch = async(req, res) => {
const { id } = req.params;
const video = await Video.findOne({_id: id});
console.log(video);
return res.render("watch", { pageTitle: video.title, video });
}
UPDARE
export const postEdit = async(req, res) => {
const { id } = req.params;
const { title, description, hashtags } = req.body;
const video = await Video.exists({_id: id});
if(!video) {
res.render("404", { pageTitle: "Video not found"});
}
await Video.findByIdAndUpdate(id, {
title,
description,
hashtags: hashtags
.split(",")
.map(word => word.startsWith('#') ? word : `#${word}`),
});
return res.redirect(`/videos/${id}`);
}
REMOVE
export const deleteVideo = async(req, res) => {
const { id } = req.params;
await Video.findByIdAndDelete(id);
return res.redirect("/");
}
METHOD
exists()
매소드를 부른 주체가 있는지 없는지 확인후 있으면 true 없으면 false를 리턴해준다.
const video = await Video.exists({_id: id});
if(!video) {
res.render("404", { pageTitle: "Video not found"});
}
Schema.static
Video에 메소드 customizing 하는법
videoSchema.static('formatHashtags', function(hashtags) {
return hashtags
.split(",")
.map(word => word.startsWith('#') ? word : `#${word}`);
});
만든 Video 메소드 사용하는 법
export const postUpload = async (req, res) => {
const { title, description, hashtags } = req.body;
try {
await Video.create({
title,
description,
hashtags: Video.formatHashtags(hashtags),
});
return res.redirect("/");
} catch (error) {
return res.status(400).render("upload", {
pageTitle: `Upload Video`,
errorMessage: error._message,
});
}
};
sort
Middleware
model을 만들기 전에 작성되어 져야함
save하기 전에 호출됨.
videoSchema.pre('save', async function() {
console.log("this",this);
this.hashtags = this.hashtags[0]
.split(",")
.map(word => word.startsWith('#') ? word : `#${word}`);
});
정규 표현식 사용하기
export const search = async(req, res) => {
const { keyword } = req.query;
let videos = [];
if (keyword) {
videos = await Video.find({
title: {
$regex: new RegExp(keyword, "i")
}
});
}
return res.render("search", { pageTitle: "Search", videos})
}