Youtube Clone Coding (4. MONGODB AND MONGOOSE)

LeeJaeHoon·2021년 10월 25일
0
post-thumbnail
  1. Mongo(terminal)

    1. 몽고 사용하기

    mongo

    1. 내가 가진 db 보기

    show dbs

    1. 현재 사용 중인 db 확인

    db

    1. 사용할 db 선택하기

    use dbName

    (현재 수업에서는 use wetube)

    1. db 컬렉션 보기

    show collections

    1. db 컬렉션 안에 documents 보기

    db.collectionName.find()

    (현재 수업에서는 db.videos.find())

    1. db 컬렉션 안에 documents 모두 제거하기

    db.collectionName.remove({})

    (현재 수업에서는 db.videos.remove({}))

  2. 사용하기

    1. npm i mongoose

    2. 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

    3. server.js 에 db.js 파일 전체 import하기

      • import "./db.js"
    4. 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를 정의해줄 수 있다.

      • default: 기본값
      • required: 꼭들어가야 하는 사항
      • trim: 공백 없애줌
      • minlength/maxlength: 문자의 최소길이/최대길이
    5. 모델 생성

      const Video = mongoose.model("Video", videoSchema);
      export default Video;
    6. 만든 Model server.js에 import하기

      • import "./models/Video.js"
    7. callback과 async/await

      • callback으로 model find하기
      export const home = (req, res) => {
        Video.find({}, (error, videos) => {
      		res.render("home", { pageTitle: "Home", videos });
      	});
      }
      • async/await로 model find하기
      export const home = async(req, res) => {
        const videos = await Video.find({});
        res.render("home", { pageTitle: "Home", videos });
      }
  3. CRUD

    1. CREATE

      • 첫번째 방법 video만들고(new Video) 저장(save())
      	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()
      • 두번째 방법 video만들고 저장 한꺼번에 해주는 create쓰기
      	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
                }
              });
      • try/catch 사용하기
      	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
                });
              }
    2. READ

      • findById
        • id를 이용하여 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 });
      }
      • findOne
        • id뿐만 아니라 다른 것들을 이용하여 찾기
      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 });
      }
    3. UPDARE

      • findByIdAndUpdate
        • id를 이용하여 update
      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}`);
      }
    4. REMOVE

      • findByIdAndDelete
        • findByIdAndRemove가 있지만 공식문서에서 특별한 이유가 있지 않은 이상 findByIdAndDelete를 써라고 되어있음.
      export const deleteVideo = async(req, res) => {
        const { id } = req.params;
        await Video.findByIdAndDelete(id);
        return res.redirect("/");
      }    
  1. 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

      • 어떻게 정렬 할 것인지 object를 통해 보낼 수 있다.
      • const videos = await Video.find({}).sort({createdAt: "desc"});
        • 최근에 만든게 제일 위로 오게 한다.
      • const videos = await Video.find({}).sort({createdAt: "asc"});
        • 오래된 것이 제일 위로 오게 한다.
  2. Middleware

    • 미들웨어는 MongoDB에서 특정 작업(저장 등)이 실행되기 전/후에 실행되는 함수들
      • pre
        • model을 만들기 전에 작성되어 져야함

        • save하기 전에 호출됨.

          videoSchema.pre('save', async function() {
            console.log("this",this);
            this.hashtags = this.hashtags[0]
              .split(",")
              .map(word => word.startsWith('#') ? word : `#${word}`);
          });
  3. 정규 표현식 사용하기

    • keyword라는 단어가 있는 제목만 찾기
    • i설정은 대소문자 구별을 안한다는 뜻
    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})
    }

0개의 댓글