Mongoose 사용하기

기운찬곰·2020년 9월 19일
9

MongoDB

목록 보기
3/4
post-thumbnail

🚀 mongodb vs mongoose

전 시간에는 mongodb라는 라이브러리를 사용했습니다. 이번 시간에는 mongoose에 대해 알아보고 실습을 해볼텐데 이 둘의 차이는 뭘까 궁금했습니다.

mongodb 라이브러리

  • MongoDB Driver 모듈입니다.
  • 따라서 mongo 콘솔 클라이언트 명령과 동일하게 조작이 가능합니다.

mongoose

  • MongoDB ODM 중 가장 유명한 라이브러리입니다.
  • 데이터베이스 연결, 스키마 정의, 스키마에서 모델로 변환, 모델을 이용해 데이터를 다룸
  • 프로미스와 콜백 사용가능

ODM : Object Document Mapping의 약자입니다. 객체와 문서를 1대 1로 매칭해줍니다. 즉, MongoDB에 있는 데이터를 NodeJS에서 Javscript 객체로 사용할 수 있도록 해줍니다.

결론 : mongodb 라이브러리는 처음에 MongoDB 명령어를 실습해보면서 개념잡기에 적합할거 같고, 실제 개발단계에서는 mongoose를 쓰는게 맞는거 같습니다.


🪁 Node JS - Mongoose 사용

설치 : npm install mongoose
( npm 공식문서 : https://www.npmjs.com/package/mongoose )

npm 문서에 가서 얼마나 사용되는지 확인해보는 재미도 쏠쏠합니다. MongoDB 사용이 지속적으로 조금씩 증가되는 모습이 보기 좋습니다. 많이 사용할수록 공부할 맛이 나잖아요.

1단계. 연결

const mongoose = require("mongoose");

mongoose
  .connect("mongodb://127.0.0.1:27017/task-manager", {
    useNewUrlParser: true,
    useCreateIndex: true,
  })
  .then(() => {
    console.log("Connected to MongoDB");
  })
  .catch((err) => {
    console.log(err);
  });

task-manager라는 DB와 연결해줍니다. 없으면 생성해줍니다.

  • useNewUrlParser : Flag for using new URL string parser instead of current (deprecated) one. (음.. deprecated 된 걸 사용하지말고 새 URL string parser를 사용하는게 좋겠죠?)
  • useCreateIndex : If true, this connection will use createIndex() instead of ensureIndex() for automatic index builds via Model.init(). (true라고하면 ensureIndex대신 createIndex를 사용한다는 뜻인거 같기는한데... 정확히는 잘 모르겠습니다)

mongoose 부터는 Promise를 사용할 수 있습니다.


2단계. 스키마 생성

const UserSchema = new mongoose.Schema({
  name: String,
  age: Number,
  saveDate: {
    type: Date,
    default: Date.now,
  },
});

MongoDB는 스키마가 없지만 Mongoose에서는 Schema를 정의해줄 수 있습니다. 컬렉션에 들어가는 문서 내부의 각 필드가 어떤 식으로 되어있는지 정의하는 객체라고 보면 됩니다.


3단계. 모델 생성

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

모델은 스키마를 사용하여 만든 인스턴스로 데이터베이스에서 실제 작업을 처리할 수 있는 함수들을 지니고 있는 객체입니다.

User라고 썼지만 실제 데이터베이스에 가보면 컬렉션이름이 users라고 되어있습니다. 뭔가 잘못된게 아닌가 생각할 수 있겠지만 MongoDB에서 컬렉션이름을 만들때 구분자를 사용하지 않고 복수형태를 사용하는게 기본이기 때문에 자동으로 그렇게 저장된거라고 볼 수 있습니다.


4단계. 객체 생성

const me = new User({
  name: "Mike",
  age: 27,
});

새로운 객체를 생성해줍니다. 하나의 Document라고 볼 수 있겠네요.


5단계. 저장

me.save()
  .then(() => {
    console.log(me);
  })
  .catch((err) => {
    console.log("Error : " + err);
  });

마지막으로 저장해주면 끝입니다.

성공적으로 저장까지 마쳤습니다.


스키마 검증(Validation)

스키마를 만들때 여러가지 옵션들이 존재합니다. 그 중에서 검증에 관련된 부분을 다뤄보려고 합니다.

required

const UserSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  
(...생략...)

스키마를 정의할 때 required를 정해줄 수 있습니다. 이렇게 되면 나중에 name을 빼먹고 저장하려고 한다면 에러가 발생할 것입니다.


validate

const UserSchema = new mongoose.Schema({
  (...생략...)
  age: {
    type: Number,
    validate(value) {
      if (value < 0) {
        throw new Error("Age must be a postive number");
      }
    },
  },
  (...생략...)

이번에는 age입니다. age는 당연히 0보다는 작으면 안됩니다. 이를 검증하도록 validate 함수를 설정했습니다.


validator 라이브러리

만약 이메일을 필드로 쓰고 싶은데 어떻게 검증을 해야할지 잘 모르겠다 싶은 분. 물론 정규식으로 할 수도 있겠습니다만 여기 좋은 라이브러리가 하나 있습니다.

npm i validator으로 설치를 해보고 사용해보겠습니다.
( validator의 여러 기능들 : https://www.npmjs.com/package/validator#validators )

const validator = require("validator");
const UserSchema = new mongoose.Schema({
  (...생략...)
  email: {
    type: String,
    required: true,
    validate(value) {
      if (!validator.isEmail(value)) {
        throw new Error("Email is invalid");
      }
    },
  },
});

이메일을 검증하려면 validator.isEmail을 사용하면 됩니다.


스키마 옵션

스키마 관련 옵션은 다양합니다. requried, default, validate도 다 그런 옵션들중 하나이고요.

string관련해서도 lowercase, uppercase, trim, minlength 등이 존재하는데 예를 들어서..

  name: {
    type: String,
    trim: true,
    required: true,
  },

이런식으로 trim을 true로 주면 name을 " hongildong " 이런식으로 줬을때 "honglidong" 식으로 앞 뒤 공백을 제거한 뒤에 저장할 수 있습니다.

지면상 여기서 다 다루지 못하며 그때그때마다 필요하면 찾아서 쓰면 될거 같습니다.
공식문서 : https://mongoosejs.com/docs/schematypes.html


마침

References

profile
배움을 좋아합니다. 새로운 것을 좋아합니다.

0개의 댓글