City At Night

[MernStack] Blog 만들기 3. MongoDB 모델링 본문

MernStack

[MernStack] Blog 만들기 3. MongoDB 모델링

Wuny 2021. 3. 4. 00:10
728x90
반응형

DB 모델링이란, 쉽게 생각하면  무언가를 만들때 아주 기본적인 형식 틀을 만든다고 생각하면 된다.
 예를 들면 자기소개서는 하나의 테이블이고 ,(mongoDB에서는  table을  collection이라 한다)
그 안에는  이름, 생년월일, 나이, 직업  등이 있다. (컬럼명이라 한다)
이름과 직업은 한글로된 문자로만 작성해야하며,
생년월일과 나이는 숫자로만 표기해야한다. 

이렇게 형식을 잡아 놓고 많은 사람들에게 자기소개서를 주면 위와 같은 형식으로 작성하게 된다. 
이게 모델링이라고 생각하면 된다.

server폴더에 models폴더를 생성해준  models폴더에서 작업을 한다.

1.  server/models/user 모델링

user는 회원가입할때 이름, 이메일,패스워드, 등급이 있고 , 그 후 post를 작성하거나 다른 post에 comment를 작성 할 수 있으며 작성한 posts와 comments들도 DB에 저장된다.

user collection인 user.js는 아래와 같다

<user.js>

import moment from 'moment'
import mongoose, { mongo } from 'mongoose'

// Create Schema  //데이터모델을 스키마라 함
const UserSchema = new mongoose.Schema({
    name : {
        type : String,
        required : true,
    },
    email :{
        type : String,
        required : true,
        unique : true,
    },
    password: {
        type : String,
        required : true,
    },
    role : {
        type : String,
        enum : ["MainJuin", "Subjuin", "User"],
        default : "User",
    },
    register_date : {
        type : Date,
        default : moment().format("YYYY-MM-DD hh:mm:ss")
    },
    comments : [
        {
            post_id :{
                type :mongoose.Schema.Types.ObjectId,
                ref : "posts",
            },
            comments_id : {
                type : mongoose.Schema.Types.ObjectId,
                ref : "comments",
            },
        },
],
    posts : [
        {
            type : mongoose.Schema.Types.ObjectId,
            ref : "posts",
        }
    ]
});

const User = mongoose.model("user", UserSchema);

export default User;

 

위에서 언급했듯이 필요한 key/Field는(컬럼) name,email,password,role,register_date,comments,post 이다.
여기서  "required" 는 꼭 작성해야하는 user collection이므로  true를 해주고
"unique"는 중복허용을 하지 않기에 true를 해준다.

2. server/models/post.js 모델링

포스트 작성할때에도 필요한 속성들이 있을것이다 . 아래 코드를 보자

<post.js>

import mongoose from  "mongoose";
import moment from 'moment'

const PostSchema = new mongoose.Schema({
    title :{
        type : String,
        required : true,
        index : true,
    },
    contents :{
        type : String,
        required : true,
    },
    views : {
        type : Number,
        default : -2
    },
    fileUrl : {
        type : String,
        default : "https://picsum.photos/200/300"
    },
    date :{
        type : String,
        default : moment().format("YYYY-MM-DD hh:mm:ss"),
    },
    category : {
        type : String,
        ref : "category"
    },
    comments : [{
        type : String,
        ref : "comment"
    }],
    creator : {
        type : mongoose.Schema.Types.ObjectId,
        ref : "user"
    },
});

const Post = mongoose.model("post", PostSchema);
export default Post;

title의  index는 찾고자 하는 글을 검색하여 노출될 수 있다고 한다. 이건 더 정확히 공부를 해보고 설명을 추가하겠다.
fileUrl의 default값은 없어도 되지만 우선 시험삼아 랜덤이미지 Url을 넣었다.

3. server/models/category.js 모델링

category는  포스트를 작성할때 이 post의 주제는 IT인지 취미인지, 스포츠인지 등등 이러한 분류를 하기 위함이다.

<category.js>

import mongoose from "mongoose";

const CategorySchema = new mongoose.Schema({
    categoryName : {
        type : String,
        default : "미분류"
    },
    posts : [
        {
            type : mongoose.Schema.Types.ObjectId,
            ref : "post",
        }
    ]
});

const Category = mongoose.model("category", CategorySchema);
export default Category;


만약 category를 안적었을시 기본값으로 "미분류"라고 한다.

post라는 key값(컬럼)은  카테고리안에 여러개의 post가 있기때문에 명시 해줬다.
 - 스포츠라는 카테고리 안에는 축구에관한 글, 선수가 부상당한 글, 역전당한 글 ,, 등등이 있다

 

4.server/models/Comment.js 모델링

작성된 글에 댓글을 적었을 때  필요한 속성들을 모델링한다.

<comment.js>

import mongoose from "mongoose";

const CommentSchema = new mongoose.Schema({
    contents : {
        type : String,
        required : true,
    },
    date : {
        type : String,
        default : moment().format("YYYY-MM-DD hh:mm:ss")
    },
    post : {
        type : mongoose.Schema.Types.ObjectId,
        ref : "post"
    },
    creator :{
        type : mongoose.Schema.Types.ObjectId,
        ref : "user"
    },
    // creatorName : {type : String}
});

const Comment = mongoose.model("comment",CommentSchema);
export default Comment;

contents의  required를 true로 한 이유는 아무 내용이 없는 댓글을 방지하기 위해서이다.
주석 처리된 부분은 작성자를 user 컬렉션을 참조하지않고 바로 DB에서 가져올 수 있기위해 작성해놓은것이라 하는데 
아직까진 잘 감이 오지 않아서 주석처리를 하였다. 추후에 유지보수를 하면서 수정하겠다.

 

다음 포스팅에는 MongoDB를 통해 지금까지 작성한 모델들을  연결해 보겠다. 

728x90
반응형
Comments