04 August 2015

Quickstart

모듈 로딩 & DB연결

on, once 를 이용해서 error 및 success시 callback.

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function (callback) {
});

Schema

basic

MongoDB에서 기본적으로 지원하지 않는 document 스키마를 설정할 수 있다.

  1. 스키마를 만든다.

     var kittySchema = mongoose.Schema({
         name: String
     });
    

    지원되는 데이터 타입은 다음과 같다.

    • String
    • Number
    • Date
    • Buffer
    • Boolean
    • Mixed
    • ObjectId
    • Array

    .

  2. 스키마에 메쏘드를 추가 (스키마가 직접 행동을 한다고?!)

     kittySchema.methods.speak = function () {
       var greeting = this.name
         ? "Meow name is " + this.name
         : "I don't have a name";
       console.log(greeting);
     }
    

    [주의]메쏘드는 다음단계에서 컴파일 하기 전에 추가해야 한다.

  3. 생성한 스키마를 모델로 컴파일 -> 생성자를 리턴

     var Kitten = mongoose.model('Kitten', kittySchema);
    
  4. 리턴받은 생성자를 이용해서 model의 인스턴스인 Document 객체 생성
    스키마에 추가한 메쏘드는 스키마가 하는 행동이 아니라 모델 객체의 메쏘드가 된다. 그러니까 얘는 db에 있는 데이터를 가지고 스스로 행동을 할 수 있는 구현체가 되는거임.

     var fluffy = new Kitten({ name: 'fluffy' });
     fluffy.speak(); // "Meow name is fluffy"
    

    Document는 사용자 정의한 메쏘드 말고도 유용한 기본 메쏘드를 많이 가지고 있다.

Static method

//추가
kittySchema.statics.findByName = function (name, cb) {
  return this.find({ name: new RegExp(name, 'i') }, cb);
}

사용
var Kitten = mongoose.model('Kitten', kittySchema);
Kitten.findByName('fluffy', function (err, kitties) {
  console.log(kitties);
});

후크

http://mongoosejs.com/docs/middleware.html

setter & getter

db내 데이터에 대한 연산을 추상화 해서 sanitizing 이나 출력을 가공하는데 유용하다.

setter
function toLower (v) {
  return v.toLowerCase();
}

var UserSchema = new Schema({
  email: { type: String, set: toLower } 
});
getter
function obfuscate (cc) {
  return '****-****-****-' + cc.slice(cc.length-4, cc.length);
}

var AccountSchema = new Schema({
  creditCardNumber: { type: String, get: obfuscate }
});

Virtual Attributes

mongoose 내에서 입출력이 가능하지만 실제로 db 에 저장되지는 않는 필드. 두개 이상의 속성을 하나의 getter / setter로 관리하거나, 패스워드를 입력한다든지 할 때, 패스워드는 가상속성으로 받고, encrypt를 해서 해시만 저장한다든지 하는데 유용하다.

get

다음과 같은 스키마가 있다고 할 때,

var PersonSchema = new Schema({
    name: {
        first: String
      , last: String
    }
});

아래와 같이 가상 속성을 만들면

PersonSchema
.virtual('name.full')
.get(function () {
  return this.name.first + ' ' + this.name.last;
});

아래처럼 편리하게 출력할 수 있다.

//console.log(person.name.first + ' ' + theSituation.name.last);
console.log(person.name.full); 
set

같은 가상 속성에 대해 다음과 같이 setter를 설정하면

.set(function (setFullNameTo) {
  var split = setFullNameTo.split(' ')
    , firstName = split[0]
    , lastName = split[1];

  this.set('name.first', firstName);
  this.set('name.last', lastName);
});

아래와 같이 간단하게 두개의 필드를 입력할 수 있다.

person.set('name.full', 'The Situation'); 

Validation

이렇게 하든지?

function validator (v) {
  return v.length > 5;
};

new Schema({
    name: { type: String, validate: [validator, 'my error type'] }
})

아니면 이렇게 하든지.

var schema = new Schema({
    name: String
})
schema.path('name').validate(function (v) {
  return v.length > 5;
}, 'my error type'); 

아니면 regex 를 쓰든지?

var schema = new Schema({
    name: { type: String, validate: /[a-z]/ }
});

아니면 built-in을 쓰든지.

var Post = new Schema({
    type: { type: String, enum: ['page', 'post', 'link'] }
})
var Person = new Schema({
    age: { type: Number, min: 5 }
})
var Person = new Schema({
    age: { type: Number, max: 100 }
})

async로 할 수도 있다. validate 함수의 파라메터를 2개 만들어 줘야 한다.

schema.path('name').validate(function (v, fn) {
  // my logic
}, 'my error type'); 

fn으로 넘어온 callback 함수는 true 나 false parameter로 실행된다.

Document

MongoDB rich query syntax 를 이용해서 Document를 DB에 바로 CRUD 할 수 있다.

C!

fluffy.save(function (err, fluffy) {
  if (err) return console.error(err);
  fluffy.speak();
});

R!

Kitten.find(function (err, kittens) {
  if (err) return console.error(err);
  console.log(kittens);
})
Kitten.find({ name: /^Fluff/ }, callback);
Kitten.find({ size: 'small' }).where('createdDate').gt(oneYearAgo).exec(callback);

U!

보통 save를 사용하면 되지만, 다음과 같이 model에서 바로update할 수 있다.

MyModel.update({ age: { $gt: 18 } }, { oldEnough: true }, fn);
MyModel.update({ name: 'Tobi' }, { ferret: true }, { multi: true }, function (err, raw) {
  if (err) return handleError(err);
  console.log('The raw response from Mongo was ', raw);
});
A.findOneAndUpdate(conditions, update, options, callback) // executes
A.findOneAndUpdate(conditions, update, options)  // returns Query
A.findOneAndUpdate(conditions, update, callback) // executes
A.findOneAndUpdate(conditions, update)           // returns Query
A.findOneAndUpdate()                             // returns Query

D!

Kitten.remove({ name: "Fluffy" }, function (err) {
  if (err) return handleError(err);
  // removed!
});


blog comments powered by Disqus
처음으로