상세 컨텐츠

본문 제목

[Node.js] 8장 몽고디비

21-22/21-22 Node.js

by juserh 2021. 12. 1. 16:43

본문

728x90
자바스크립트 문법
NoSQL

1. NoSQL vs. SQL

  • SQL(MySQL): 
    • 규칙에 맞는 데이터 입력
    • 테이블 간 JOIN 지원
    • 안전성, 일관성
    • 용어(테이블, 로우, 컬럼)
  • NoSQL(몽고디비):
    • 자유로운 데이터 입력
    • 컬렉션 간 JOIN 미지원: 동시에 쿼리를 수행하는 경우 쿼리가 섞여 예상치 못한 결과를 낼 가능성이 있음
    • 확장성, 가용성
    • 용어(컬렉션, 다큐먼트, 필드): 고정된 테이블 X

2. 몽고디비 설치하기

1. https://www.mongodb.com/try/download/community

 

MongoDB Community Download

Download the Community version of MongoDB's non-relational database server from MongoDB's download center.

www.mongodb.com

2. C:\data\db 폴더 만들기: 데이터가 저장될 폴더

3. 몽고디비 실행: C:\Program Files\MongoDB\Server\5.0\bin 콘솔(1)에서 mongod명령어 입력

몽고디비 실행

4. 몽고디비 프롬프트(>) 접속: C:\Program Files\MongoDB\Server\5.0\bin 콘솔(2)에서 mongo 명령어 입력

몽고디비 프롬프트 실행

5. 관리자 계정 추가

use admin

db.createUser({user: '이름', pwd: '비밀번호', roles: ['root']})

 

6. mongod를 입력한 콘솔(1)을 종료한 뒤, mogod --auth명령어로 접속

7. mongo를 입력했던 콘솔(2) 종료한 뒤, mongo admin -u 이름 -p 비밀번호    명령어로 접속

3. 컴퍼스 설치하기

컴퍼스: 몽고디비 관리도구, GUI를 통해 데이터를 시각적으로 관리할 수 있어 편리

(4) 커넥션 생성하기

1. 몽고디비 실행한 후 컴퍼스로 접속 

2. New Connection 화면에서 Fill in connection fields individualy 클릭

3. Authentication을 User/Password로 바꾸고 몽고디비 계정 이름과 비밀번호 입력, CONNECT 버튼을 눌러 localhost:27017에 접속(admin, config, local 데이터베이스)

localhost에 접속한 화면

4. 데이터베이스 및 컬렉션 생성하기

몽고디비 콘솔에서 데이터베이스,컬렉션 생성

  • use [데이터베이스명]  : 데이터베이스 생성
  • show dbs  : 데이터베이스 목록 확인(데이터를 최소 한 개 이상 넣어야 목록에 표시)
  • db  : 현재 사용 중인 데이터베이스 확인
  • db.createCollection('컬렉션 이름')  : 컬렉션 생성(컬렉션을 따로 생성하지 않아도 됨, 다큐먼트를 넣는 순간 컬렉션도 자동 생성)
  • show collections  : 생성한 컬렉션 목록 확인

5. CRUD 작업하기

(1) Create(생성)

컬렉션에 컬럼을 정의하지 않아도 되므로 컬렉션에는 아무 데이터나 넣을 수 있음
자바스크립트 자료형 + 추가 자료형

몽고디비 자료형: Data나 정규표현식 같은 자바스크립트 객체

                       Binary Data, ObjectId, Int, Long, Decimal, Timestamp, JavaScript 등의 추가적인 자료형

                       Undefined와 Symbol은 몽고디비에서 자료형으로 사용되지 않음

users 다큐먼트 생성

  • db.컬렉션명.save(다큐먼트)  :다큐먼트 생성
  • new Date()  : 현재 시간 입력
  • WriteResult({"nInserted":1})  :명령이 성공적으로 수행될 시의 응답

comments 다큐먼트 생성

(2) Read(조회)

users, comments 다큐먼트 조회

  • db.컬렉션명.find({})  : 컬렉션 내의 모든 다큐먼트 조회

특정 필드만 조회

  • db.컬렉션명.find({}, {필드: 0 or 1})  : find 메서드의 두 번째 인수에 조회할 필드 입력, 1 또는 true로 표시된 필드만 가져옴(_id는 기본적으로 가져오게 되어 있으므로 0 또는 false를 입력해 가져오지 않도록 할 수 있음).

조건에 맞는 다큐먼트 조회

  • db.컬렉션명.find({조건}, {필드: 0 or 1})  : 조회 시 조건을 첫 번째 인수 객체에 기입
  • 몽고디비 특수 연산자: $gt(초과), $gte(이상), $lt(미만), $lte(이하), $ne(같지 않음), $or(또는), $in(배열 요소 중 하나) 등

$or 조건 조회

  • db.컬렉션명.find({$or: [조건 배열]} ,{})  : $or에 주어진 배열 안의 조건들을 하나라도 만족하는 다큐먼트 조회

조회 정렬

  • 조회.sort({정렬 기준 필드: 1 or -1})  : 내림차순 -1, 오름차순 1

조회 다큐먼트 개수 제한

  • 조회.limit(제한할 개수)  :조회할 다큐먼트 개수 설정

다큐먼트 개수 설정, 건너뛰기

  • 조회.limit(제한할 개수).skip(건너뛸 개수)  :입력한 개수만큼 다큐먼트를 건너 뛰고 그 후 다큐먼트 반환

(3) Update(수정)

기존 데이터 수정

  • db.컬렉션명.update({수정할 다큐먼트 지정}, {수정할 내용})  : 수정 성공 시 첫 번째 객체에 해당하는 다큐먼트 수(nMatched)와 수정된 다큐먼트 수(nModified) 반환
  • $set 연산자  : 일부 필드만 수정

(4) Delete(삭제)

다큐먼트 삭제, 조회

  • db.컬렉션명.remove({삭제할 다큐먼트에 대한 정보})  : 삭제 성공 시 삭제된 개수 반환

6. 몽구스 사용하기

ODM(Object Document Mapping): 몽고디비는 릴레이션이 아니라 다큐먼트를 사용
몽고디비에 없는 기능들을 몽구스가 보완: 스키마(몽고디비에 데이터 넣기 전에 노드 서버에서 필터링), populate 메서드(JOIN 기능)
ES2015 프로미스 문법과 강력하고 가독성이 높은 쿼리 빌더 지원

패키지 설치: npm i express morgan nunjucks mongoose

                 npm i -D nodemon

(1) 몽고디비 연결하기

mongoose.connect('mongodb://[username]:[password]@localhost:27017/admin', {
        dbName: 'nodejs',
        useNewUrlParser: true,
        useCreateIndex: true,
    }, (error) => {
        if (error) {
        console.log('몽고디비 연결 에러', error);
        } else {
        console.log('몽고디비 연결 성공');
        }
    });

(2) 스키마 정의하기

const mongoose = require('mongoose');

const { Schema } = mongoose;
const userSchema = new Schema({
    name: {
        type: String,
        required: true,
        unique: true,
    },
    age: {
        type: Number,
        required: true,
    },
    married: {
        type: Boolean,
        required: true,
    },
    comment: String,
    createdAt: {
        type: Date,
        default: Date.now,
    },
});

module.exports = mongoose.model('User', userSchema);

 

 

const mongoose = require('mongoose');

const { Schema } = mongoose;
const { Types: { ObjectId } } = Schema;
const commentSchema = new Schema({
    commenter: {
        type: ObjectId,
        required: true,
        ref: 'User',
    },
    comment: {
        type: String,
        required: true,
    },
    createdAt: {
        type: Date,
        default: Date.now,
    },
});

module.exports = mongoose.model('Comment', commentSchema);
  • Schema({})  : 스키마 생성자
  • _id  : 기본 키 자동 생성되므로 적어줄 필요 없음
  • ref 속성 :해당 필드에 ref속성 스키마의 ObjectId가 들어감 -> JOIN 기능

(3) 쿼리 수행하기

const express = require('express');
const User = require('../schemas/user');

const router = express.Router();

router.get('/', async (req, res, next) => {
    try {
        const users = await User.find({});
        res.render('mongoose', { users });
    } catch (err) {
        console.error(err);
        next(err);
    }
});

module.exports = router;
  • find({})  : 조회
const express = require('express');
const User = require('../schemas/user');
const Comment = require('../schemas/comment');

const router = express.Router();

router.route('/')
    .get(async (req, res, next) => {
        try {
        const users = await User.find({});
        res.json(users);
        } catch (err) {
        console.error(err);
        next(err);
        }
    })
    .post(async (req, res, next) => {
        try {
        const user = await User.create({
            name: req.body.name,
            age: req.body.age,
            married: req.body.married,
        });
        console.log(user);
        res.status(201).json(user);
        } catch (err) {
        console.error(err);
        next(err);
        }
    });

router.get('/:id/comments', async (req, res, next) => {
    try {
        const comments = await Comment.find({ commenter: req.params.id })
        .populate('commenter');
        console.log(comments);
        res.json(comments);
    } catch (err) {
        console.error(err);
        next(err);
    }
});

module.exports = router;
  • create({필드 지정})  : 생성
  • populate(필드)  : JOIN과 비슷한 기능으로, 관련 있는 컬렉션의 다큐먼트를 불러 옴(users컬렉션에서 사용자 다큐먼트를 찾아 합침).
const express = require('express');
const Comment = require('../schemas/comment');

const router = express.Router();

router.post('/', async (req, res, next) => {
    try {
        const comment = await Comment.create({
        commenter: req.body.id,
        comment: req.body.comment,
        });
        console.log(comment);
        const result = await Comment.populate(comment, { path: 'commenter' });
        res.status(201).json(result);
    } catch (err) {
        console.error(err);
        next(err);
    }
    });

router.route('/:id')
    .patch(async (req, res, next) => {
        try {
        const result = await Comment.update({
            _id: req.params.id,
        }, {
            comment: req.body.comment,
        });
        res.json(result);
        } catch (err) {
        console.error(err);
        next(err);
        }
    })
    .delete(async (req, res, next) => {
        try {
        const result = await Comment.remove({ _id: req.params.id });
        res.json(result);
        } catch (err) {
        console.error(err);
        next(err);
        }
    });

module.exports = router;
  • update({수정할 다큐먼트 특정하는 쿼리 객체}, {수정할 필드와 내용})  : 수정
  • remove({삭제할 다큐먼트 조건})  : 삭제

 

혹시! 연결이 계속 안되는 오류가 반복된다면, mongoose 버전 문제일 수 있으니,

        npm uninstall mongoose      

        npm i moongoose@4   

 

*퀴즈*

1. 몽고디비는 (NoSQL/SQL) 데이터베이스이다.

2. 몽고디비는 JOIN기능은 없지만 이와 비슷한 기능을 하는 (populate)메서드를 가진다.

3. 몽고디비는 테이블 대신 (컬렉션)이라는 개념을 가지고 이 점 때문에 (컬럼)을 따로 정의하지 않는다.

4. 몽고디비를 실행하는 명령어는 (mongod)이다.

5. 몽고디비에서 users컬렉션에 있는 모든 다큐먼트를 나이가 적은 순서대로 정렬하는 명령어는?

   db.users.find({}).sort({age: 1})

6. mysql의 시퀄라이즈가 있다면 몽고디비에는 (몽구스)가 있다. 이것은 릴레이션이 아니라 다큐먼트를 사용하므로 (ODM)이라고 부른다.

728x90

관련글 더보기