본문 바로가기
JavaScript│Node js

Node js Mongoose 사용하기

by 자유코딩 2018. 10. 15.

Mongoose 는 node js 전용 ODM(Object Data Mapping) 이다.


쉽게 말하면 Node js 코드에서 Mongo DB 를 편리하게 조작하도록 해준다.


사용하려면 일단 Mongoose 패키지를 설치한다.


npm 설치


npm init


mongoose 설치


npm install --save express mongoose body-parser



이렇게 하면 되는 것은 맞다.


그런데 독자가 따라하기엔 이게 더 좋을 것 같다.


Express Generator 를 사용해서 프로젝트를 만들려고 한다.


Express Generator 설치


npm install express-generator -g


Express 앱 생성


express --view=ejs 앱이름


여기까지만 진행하고 npm start 를 하면 에러가 발생한다.


npm 도 설치한다.


npm install


생성한 앱은 npm start 로 실행한다.


npm start


이제 생성한 앱에 mongoose를 설치한다.


npm install --save express mongoose body-parser


app.js 파일을 작성 해보겠다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// app.js
 
......
......
 
// [LOAD PACKAGES]
var bodyParser  = require('body-parser'); // body parser 도 불러온다.
var mongoose    = require('mongoose'); // 설치한 mongoose 를 불러온다.
 
// [CONFIGURE APP TO USE bodyParser]
app.use(bodyParser.urlencoded({ extended: true })); //body-parser 를 사용한다.
app.use(bodyParser.json()); // body-parser 의 json 을 사용한다.
 
// [CONFIGURE SERVER PORT]
var port = process.env.PORT || 8080//굳이 작성하지 않아도 된다.
 
// [CONFIGURE ROUTER]
var router = require('./routes')(app) //express 생성기로 생성했다면 이미 있는 부분
 
// [RUN SERVER]
var server = app.listen(port, function(){
 console.log("Express server has started on port " + port) // 실행 후 콘솔에 표시하기 위한 것. 굳이 작성 안해도 된다.
});
 
 
......
......
cs



이제 index.js 도 고쳐본다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
......
......
 
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose'); // mongoose 모듈 불러오기
const db = mongoose.connection; // mongoose 연결을 할 변수 지정
 
db.on('error'console.error.bind(console,'connection error : ')); // 에러 발생시
 
db.once('open'function () { // 연결이 되었을 때
    console.log('mongoose connected');
});
 
mongoose.connect('mongodb://localhost/test'); // 연결 db 주소
 
/* GET home page. */
router.get('/'function(req, res, next) {
  res.render('index', { title: 'Express' });
});
 
router.get('/mongoose/insert'function (req, res) {
 
 
});
 
router.get('mongoose/select'function (req, res) {
 
 
});
 
router.get('mongoose/update'function (req, res) {
 
 
});
 
router.get('mongoose/delete'function (req, res) {
 
 
});
 
module.exports = router;
 
......
......
cs



CRUD 모두를 url 로 접근해서  해 볼 생각이다.


자 이제 몽구스를 사용해서 CRUD 를 해 볼 것인데.


그 전에 Mongoose 에는 스키마라는 것이 있다. Mongo DB 에 있는 개념은 아니다.


이것을 먼저 살펴보려고 한다.


스키마의 정의는 아래 코드처럼 하면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var mongoose = require('mongoose');
  var Schema = mongoose.Schema;
 
  var blogSchema = new Schema({
    title:  String,
    author: String,
    body:   String,
    comments: [{ body: String, date: Date }],
    date: { type: Date, default: Date.now },
    hidden: Boolean,
    meta: {
      votes: Number,
      favs:  Number
    }
  });
cs


1. mongoose 모듈을 불러온다.


2. mongoose에 있는 Schema 를 변수에 저장한다.


3. Schema 객체를 생성한다.


코드에서는 title, author , body , comments, date, hidden, meta 등이 보인다.


이것들은 이후 Database 에서 속성(필드) 역할을 한다.


데이터베이스 테이블을 만드는 것과 비슷하다고 보면 된다.


사용할 수 있는 스키마 타입은 이렇다.


1
2
3
4
5
6
7
8
9
10
String
Number
Date
Buffer
Boolean
Mixed
ObjectId
Array
Decimal128
Map
cs


위의 코드를 보면 "스키마가 테이블 생성을 하는 구나" 하고 생각 할 수 있다.


스키마는 테이블 생성만 하지는 않는다.


스키마의 정의를 통해서 instance method , static model method , compund indexes 도 정의 할 수 있다.


쉽게 말해 스키마와 관련된 함수를 정의하고 쓸 수 있다는 것이다.


compund index는 관계형 db의 인덱스를 생각하면 된다.


index 를 사용해서 빨리 탐색하는 기능을 지원한다.



instance method


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const Schema = mongoose.Schema; // 스키마를 생성하기 위한 변수 할당
 
let animalSchema = new Schema({ nameString, type: String }); // 스키마를 정의한다.
 
animalSchema.methods.findSimliarTypes = function (cb) { // 스키마의 인스턴스 메소드를 정의한다.
  return this.model('Animal').find({ tpye : this.type }, cb);
};
 
let Animal = mongoose.model('Animal', animalSchema); // 정의한 스키마는 모델로 변환해야 쓸 수 있다. 스키마를 모델로 변환한다.
 
let dog = new Animal({ type : 'dog' }); // 변환한 모델의 객체를 생성한다.
 
dog.findSimilarTypes(function (err ,dogs) { // 객체의 함수를 호출한다. (인스턴스 메소드 호출)
    console.log(dogs);
});
cs



static method 


1
2
3
4
5
6
7
8
9
10
11
12
13
let animalSchema = new Schema({ nameString, type: String }); // 스키마 정의
 
animalSchema.statics.findByName = function(name, cb) { // 스키마의 static 메소드 정의
    return this.find({ namenew RegExp(name'i') }, cb);
};
 
var Animal = mongoose.model('Animal', animalSchema); // 스키마를 사용하기 위해서 모델로 변환
 
Animal.findByName('fido'function(err, animals) { //static 메소드 
 
  console.log(animals);
 
});
cs


Query Helpers


몽구스는 node js 코드 안에서 쿼리를 사용할 수 있도록 해주는 Query  Helper가 있다.


쿼리 헬퍼는 아래와 같이 생겼다. 스프링에서는 Mybatis를 사용할 때 인터페이스를 써서 쿼리를 보낸다.


스프링의 쿼리 인터페이스와 비슷한 개념이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
 animalSchema.query.byName = function(name) {
    return this.where({ namenew RegExp(name'i') });
  };
 
  var Animal = mongoose.model('Animal', animalSchema);
 
  Animal.find().byName('fido').exec(function(err, animals) {
    console.log(animals);
  });
 
  Animal.findOne().byName('fido').exec(function(err, animal) {
    console.log(animal);
  });
cs


작성한 코드의 이름들을 살펴보면. 


findOne , find , query.byName 등의 이름으로 되어있다.


굳이 써보지 않아도 , findOne은 row 한 개를 select 하는 것으로 보인다.


find().byName 은 괄호 안의 조건을 만족하는 행들을 찾는 것으로 보인다.


query.byName() 은 name 을 key로 사용해서 행을 찾는 것으로 보인다.


중간에 var Animal = mongoose.model() 을 사용해서 모델로 변환하고 있다.


다음은 인덱스다.


SQL DB 처럼 MongoDB도 인덱스를 제공한다.


인덱스는 컬럼에 추가하는 것으로 , 테이블의 탐색 속도를 향상시켜준다.


자주 조회되는 필드를 따로 저장해서 탐색 속도를 향상시킨다.


1
2
3
4
5
db.nettuts.createIndex({ "last"1 }); // 단일 인덱스 생성
 
db.nettuts.createIndex({ name1, hp: 1, xp: 1 }); // 여러 개의 인덱스 생성
 
db.nettuts.getIndexes(); // 인덱스들 확인 
cs



Virtual 기능


Virtual 은 컬럼에 없는 값인데 있는 것처럼 사용 할 수 있는 기능이다.


SQL DB 에서는 두개 이상의 컬럼을 조합해서 select 결과를 만들어 내기도 한다.


만약에 이럴때 조합된 여러 개의 컬럼들이 하나의 컬럼처럼 동작한다면 편리할 것이다.


그렇게 존재하는 가상의 조합된 컬럼이 Virtual 이다.


아래 코드를 한번 보자. Virtual 을 사용하지 않은 경우이다.


아래 코드는


1. 스키마를 정의한다.


2. 모델로 변환한다.


3. 모델의 객체를 생성한다.


4. 모델을 사용해서 스키마의 컬럼을 이어 붙인다.


5. 출력한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let personSchema = new Schema({ // 스키마가 정의 됨
    name: {
        first: String,
        last: String
    }
});
 
let Person = mongoose.model('Person',personSchema); // 모델로 변환한다.
 
let ax1 = new Person({ // 모델의 객체를 생성한다.
   name: { first: 'Axl', last: 'Rose'}
});
 
function exportMethod(){ // 컬럼을 붙여서 출력한다.
    console.log(ax1.name.first + ' ' + ax1.name.last);
}
 
cs


실행하면 axl Rose가 출력 될 것이다.


이렇게 매번 문자열을 이어 붙이면 불편하다.


이럴때 Virtual 을 사용한다.


1
2
3
personSchema.virtual('fullName').get(function () {
  return this.name.first + ' ' + this.name.last;
});
cs
















댓글