[Node.js] 8장 몽고디비
자바스크립트 문법
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 데이터베이스)
4. 데이터베이스 및 컬렉션 생성하기
- use [데이터베이스명] : 데이터베이스 생성
- show dbs : 데이터베이스 목록 확인(데이터를 최소 한 개 이상 넣어야 목록에 표시)
- db : 현재 사용 중인 데이터베이스 확인
- db.createCollection('컬렉션 이름') : 컬렉션 생성(컬렉션을 따로 생성하지 않아도 됨, 다큐먼트를 넣는 순간 컬렉션도 자동 생성)
- show collections : 생성한 컬렉션 목록 확인
5. CRUD 작업하기
(1) Create(생성)
컬렉션에 컬럼을 정의하지 않아도 되므로 컬렉션에는 아무 데이터나 넣을 수 있음
자바스크립트 자료형 + 추가 자료형
몽고디비 자료형: Data나 정규표현식 같은 자바스크립트 객체
Binary Data, ObjectId, Int, Long, Decimal, Timestamp, JavaScript 등의 추가적인 자료형
Undefined와 Symbol은 몽고디비에서 자료형으로 사용되지 않음
- db.컬렉션명.save(다큐먼트) :다큐먼트 생성
- new Date() : 현재 시간 입력
- WriteResult({"nInserted":1}) :명령이 성공적으로 수행될 시의 응답
(2) Read(조회)
- 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(배열 요소 중 하나) 등
- 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)이라고 부른다.