Elice SW engineer - TIL day 30

Circlewee·2022년 5월 13일
0

Elice SW 2 TIL

목록 보기
27/31

1. MongoDB

1.1 기본 개념

  1. Database: 하나 이상의 collection을 가질 수 있는 저장소
    SQL에서의 database와 유사
  2. collection: 하나 이상의 document가 저장되는 공간
    SQL에서의 table과 유사하지만 collection이 document의 구조를 정의하지 않음
  3. document: MongoDB에 저장되는 자료
    SQL에서의 row와 유사. JSON, BSON등 다양한 자료형 지
    • ObjectID: SQL의 primary key와 유사. document를 생성할 때 자동으로 생성되는 값(난수)

2. Mongoose ODM

  • Object Data Modeling
    MongoDB의 collection에 집중하여 관리하도록 도와주는 패키지

2.1 사용 이유

  1. 연결 관리: 기본 Node.js드라이버가 관리하기 어려운 연결 상태를 간단하게 괸리할 수 있음
  2. 스키마 관리: Code-level에서 스키마를 정의하고 관리할 수 있음.
    • 스키마를 정의하지 않고 사용하는 것이 NoSQL의 장점이지만 코드 작성과 프로젝트 관리의 유용성을 위해 정의하는 것이 좋다.
  3. Populate: MongoDB에서는 join을 제공하지 않고 aggregate라는 복잡한 쿼리를 제공
    Mongoose는 populate를 사용하여 간단하게 구현 가능

2.2 사용하기

2.2.1 Schema정의

const { Schema } = require('mongoose');

// convention
const PostSchema = new Schema({
  title: String,
  content: String,
}, {
  timestamps: true,
});
  • collection에 저장될 document의 스키마를 code-level에서 관리하기 위해 작성
    다양한 형식을 미리 지정하여 생성, 수정 작업 시 데이터 형식을 체크
  • timestamps 옵션을 사용하면 생성, 수정 시간을 자동으로 기록해줌

2.2.2 model만들기

const mongoose = require('mongoose');
const PostSchema = require('./schemas/board')

exports.Post = mongoose.model('Post', PostSchema);
// module.exports = mongoose.model('Post', PostSchema);
  • 작성된 Schema를 mongoose에서 사용할 수 있는 모델로 만드는 코드
    'Post': 모델의 이름

2.2.3 데이터베이스 연결

const mongoose = require('mongoose');
const { Post } = require('./models');

mongoose.connect('DBURL');
  • connect 메소드를 이용하여 간단하게 데이터베이스에 연결할 수 있음

2.2.4 model사용하기

2.2.3의 코드에서 연결

  1. create
async function create() {
  const created = await Post.create({
    title: 'first title',
    content: 'first article',
  });
  
  // object array 전달로 복수의 document를 생성할 수 있다.
  const multipleCreated = await Post.create([
    item1,
    item2
  ]);
}   
  1. read(find)
async function read() {
  const postLists = await Post.find(query);
  const onePost = await Post.findOne(query);
  const postById = await Post.findById(id);
}
  1. update
async function update() {
  // update~는 쿼리의 결과를 반환
  const updateResult = await Post.updateOne(query, {
    ...
  });
  const updateResults = await Post.updateMany(query, {
    ...
  });
  
  // find~ 함수들은 검색된 document를 업데이트하여 반환해 줌
  const updateById = await Post.findByIdAndUpdate(id, {
    ...
  });
  const onePost = await Post.findOneAndUpdate(query, {
    ...
  });
}
  • Mongoose의 update는 기본적으로 $set operator를 사용하여 document를 통째로 변경하지 않는다. (MongoDB의 update와 다름)
  1. delete
async function del() {
  const deleteResult = awiat Post.deleteOne(query);
  const deleteResults = await Post.deleteMany(query);
  const onePost = await Post.findOneAndDelete(query);
  const postById = await Post.findByIdAndDelete(id);
}
  • update와 비슷한 맥락
  1. populate
const Post = new Schema({
  ...
  user: {
    type: Schema.Types.ObjectId,
    ref: 'User' // 여기에 입력한 값을 기준으로 populate한다.
  },
  comments: [{
    type: Schema.Types.ObjectId,
    ref: 'Comment'
  }],
});

// 적용하고자 하는 파일에 추가
const post = await Post.find().populate(['user', 'comments']);
  • document안에 document를 담지 않고 ObjectID를 가지고 referenct하여 사용
  • 사용할 때 populate하여 하위 document처럼 사용할 수 있게 해준다.
  • 단일 객체 혹은 object array로 사용가능
  • ref: '': 앞에서 model을 선언할 때 사용한 name과 같음

2.3 Use with Express

  • 일반적으로 models 디렉토리에 Schema와 Model을 같이 위치
  • app객체는 앱의 시작을 의미하는 부분이므로 해당 부분에 데이터베이스 연결을 명시하는 Mongoose.connect를 위치한다.
  • Express.js 앱은 종료되지 않고 동작하기 때문에 계속해서 정상적으로 동작하는 지 확인하는 데이터베이스 연결 관련 이벤트 처리를 하는 것이 좋다.
profile
공부할 게 너무 많아요

0개의 댓글

관련 채용 정보