What to do

이번에는 mongoose 를 이용하여 NodeJS 에서 mongoDB를 사용해보자


mongoose

mongoose가 뭐지❓

mongoose 는 NodeJS에서 mongoDB를 사용 할 수 있게 도와주는 라이브러리이다

mongoose 설치

npm 또는 yarn 같은 패키지 매니저를 다운 받으면 된다

npm install mongoose
yarn add mongoose

mongoDB와 연결

먼저 DB를 불러오는 파일에 mongoose를 이용해 연결해주자

db.js

import mongoose from "mongoose";

mongoose.connect('mongodb://localhost:27017/test', {
  useNewUrlParser: true,
  useFindAndModify: false
});

const db = mongoose.connection;

const handleOpen = () => console.log("➡️ connected to DB");
const handleError = (err) => console.log(`❌ Error on DB Connection : ${err}`);

db.once("open", handleOpen);
db.on("error", handleError);

mongoose.connect() 메서드를 사용하면 mongoDB 서버와 연결된다

인자로 ( mongoDB_URL, options ) 를 넣었는데 URL에 있는 PORT는 mongoDB 서버를 열 때 나온다

options

  • useNewUrlParser : 사용하면 mongoDB_URL에 PORT를 넣을 수 있다
  • useFindAndModify : 문서에 따르면 false로 설정하면 findAndModify() 대신에 네이티브 함수인 findOneAndUpdate()를 사용하게 된다고 한다
    (아직 써본적 없는 부분이라 추후에 다루게 되면 수정해야지😚)

Schema

mongoDB는 JSON 형식으로 데이터를 저장하지만, mongoose를 사용하여 모델의 형태를 정할 수 있다

models/Video.js

import mongoose from "mongoose";

const VideoSchema = new mongoose.Schema({
  fileUrl: {
    type: String,
    required: "FileURL is required!"
  },
  title: {
    type: String,
    required: "Title is required!"
  },
  description: String,
  views: {
    type: Number,
    default: 0
  },
  createdAt: {
    type: Date,
    default: Date.now
  },
  comments: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Comment"
    }
  ]
});

이런 식으로 스키마를 만들어 데이터의 type이나 required, default 값 등을 설정 할 수 있다

Model 생성

이제 앞서 만든 스키마를 가지고 데이터베이스에 저장할 모델을 만들어보자

const model = mongoose.model("Video", VideoSchema);

몽고DB에 Video 라는 모델이 만들어졌다
이 모델을 이용해서 데이터베이스에 있는 데이터를 생성, 조회, 변경, 삭제를 할 수 있다

질의문(queries)

  • 생성(create)
model.create({ 
  fileUrl:"_url", 
  title:"Happy video",
  description:"lalalalal"
});
  • 조회(find)
// 조건으로 찾기
model.find({title:"Happy video"},(err,res)=>{
  console.log(res);
});
// id로 찾기
model.findById(1123);
  • 변경(update)
// title이 "Happy video"인 데이터의 description을 "changed"로 바꿔라
model.findOneAndUpdate({title:"Happy video"}, {description:"changed!"});
  • 삭제(delete)
model.findOneAndDelete({title:"Happy video"});

위 모든 함수에 다음 인자로 CALLBACK 함수가 들어갈 수 있는데
function(err, docs){}의 형태로 에러와 들어간 데이터정보가 인자로 들어간다

이 외에도 여러 좋은 함수들이 있으니 문서를 참조하는 것이 베스트다!

참조(reference)

관계형 데이터베이스에는 참조키, 외래키 등 데이터끼리 관계가 있는데, mongoose로도 조금의 관계를 만들 수 있다

Schema를 생성할 때

import mongoose from "mongoose";

const VideoSchema = new mongoose.Schema({
  fileUrl: {
    type: String,
    required: "FileURL is required!"
  },
  title: {
    type: String,
    required: "Title is required!"
  },
  comments: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Comment"  // Comment 모델을 참조
    }
  ],
  creator : {
      type: mongoose.Schema.Types.ObjectId,
      required: "Creator is required!",
      ref : "User"   // User 모델을 참조
    }
});

const Video = mongoose.model("Video", VideoSchema);

위의 creator 나 comments 는 다른 데이터 모델을 참조 한 것이다

객체를 생성할 때에는 참조 상관없이 생성하면 된다

// 유저 객체
const userInstance = User.create({
  name : "Deviden"
});
// 비디오 객체
const videoInstance = Video.create({
  fileUrl : "http://videoexample.com/video1",
  title : "video title",
  creator : userInstance.id
});

만약 비디오 객체에서 Creator 정보까지 얻고 싶을 때는 참조되어있는 값을 이용하면 된다

조건

  • 참조 값은 반드시 해당 객체의 Object_id 이어야 한다

Populate

Populate() 메서드는 Object_id 를 이용하여 해당 모델에서 데이터를 가져와 채워준다. 인자로 데이터를 채울 변수명을 넣으면 된다

const video = Video.find({title : 'video title'}).populate('creator');
console.log(video);

위의 코드를 실행하면 아래처럼 나오게 된다

{
  _id : 125124125,
  fileUrl : 'http://videoexample.com/video1',
  title : 'video title',
  creator : {
    _id : 12321415,
    name : 'Deviden'
  }
}

이렇게 참조 되어 있는 데이터를 불러올 수 있다

아마 다른 기능이 더 있을 테지만 지금은 여기까지만,,,

connect-mongo

mongoDB의 세션스토어에 express와 mongoose connection으로 연결되어 있을 때, 서버를 재시작하면 연결이 끊어진다. 이럴 때 connect-mongo를 사용하면 연결을 유지할 수 있다.

단, 모든 상황에서 가능한건 아니고, 이미 연결되어있는 상태에서 재시작할 때에만 가능하다

Document : https://www.npmjs.com/package/connect-mongo

Install

npm install connect-mongo

Usage

app.js

import session from 'express-session';
import mongoose from 'mongoose';
import MongoStore from 'connect-mongo';

const cookieStore = MongoStore(session); 
// 이제 세션을 이 저장소에 저장하게 된다

app.use(session({
    secret: 'secret',  // 이번 강의랑 아무 상관 없다
    store: new cookieStore({ mongooseConnection: mongoose.connection })
  // 저장소를 mongoose를 통해 몽고 DB와 연결해준다
}));

이렇게 해주면 새로운 저장소에 세션이 저장된다

이제 서버를 재시작해도 기존에 저장되어있던 세션은 그대로 남아 있을 것이다