티스토리 뷰

Mongoose/schemas

Virtuals

mongoT 2020. 3. 9. 19:03

virtuals는 MongoDB에 실재하지 않는 access property(getter나 setter)다.

getter는 formatting이나 combining 하는데 유용하고

setter는 하나의 값을 여러개의 값으로 분해하는데 유용하다.

Axl Rose라는 사람이 있다고 하면

  // define a schema
  var personSchema = new Schema({
    name: {
      first: String,
      last: String
    }
  });

  // compile our model
  var Person = mongoose.model('Person', personSchema);

  // create a document
  var axl = new Person({
    name: { first: 'Axl', last: 'Rose' }
  });

이 사람의 fullName을 또 따로 저장하고 싶지는 않지만 code상에서 쓰고 싶을 때

console.log(axl.name.first + ' ' + axl.name.last); // Axl Rose

이렇게 할 것이다.

그런데 이렇게 하는 게 귀찮기 때문에 가상의 접근자 프로퍼티 fullName을 만든다.

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

이렇게 fullName으로 get 할 수 있으나 setter를 설정하지 않아서 값을 바꿀 수는 없다.

console.log(axl.fullName); // 'Axl Rose'
axl.fullName = 'Willam Rose';
console.log(axl.fullName); // 'Axl Rose'

setter와 getter는 chainable 하게 설정해줄 수 있다.

personSchema.virtual('fullName')
    .get(function () {
        return this.name.first + ' ' + this.name.last;
    })
    .set(function (v) {
        this.name.first = v.slice(0, v.indexOf(' '));
        this.name.last = v.slice(v.indexOf(' ') + 1);
    });

이제 set가능. 이 setter는 name.first랑 name.last를 바꿨기 때문에 document의 name property도 바뀌어 있다.

axl.fullName = 'Willam Rose';
console.log(axl.fullName); // 'Willam Rose'

document를 순수한 javascript object로 바꿔주는 toObject() 매서드나 toJSON()가 호출했을 때 object에는 이 virtual property가 당연히 없다.

let H = mongoose.model('Human', personSchema);
let h = new H({ "name.first": 'jack', "name.last": 'sparrow' });
h.fullName = "Will Turner"

console.log(h.toObject());
// {
//     name: { first: 'Will', last: 'Turner' },       
//     _id: 5e64c7a28774305324354edf,
//     id: '5e64c7a28774305324354edf'
//   }
console.log(h.toJSON());
// {
//     name: { first: 'Will', last: 'Turner' },       
//     _id: 5e64c7a28774305324354edf,
//     id: '5e64c7a28774305324354edf'
//   }
console.log(JSON.stringify(h));
// {"name":{"first":"Will","last":"Turner"},"_id":"5e64ca6d98bbae458c82cbe3","id":"5e64ca6d98bbae458c82cbe3"}

만약 toJSON()이나 toObject() 한 결과로 나온 객체에 이 virtual 프로퍼티가 포함되게 하고 싶다면 virtuals를 true로 설정하면 된다.

// Documents have a toObject method which converts the mongoose document into a plain javascript object.
personSchema.set('toObject', { virtuals: true });
//Exactly the same as the toObject option but only applies when the documents toJSON method is called.
personSchema.set('toJSON', { virtuals: true });
console.log(h.toObject());
// {
//     name: { first: 'Will', last: 'Turner' },       
//     _id: 5e64c7a28774305324354edf,
//     fullName: 'Will Turner',
//     id: '5e64c7a28774305324354edf'
//   }
console.log(h.toJSON());
// {
//     name: { first: 'Will', last: 'Turner' },       
//     _id: 5e64c7a28774305324354edf,
//     fullName: 'Will Turner',
//     id: '5e64c7a28774305324354edf'
//   }
console.log(JSON.stringify(h));
// {"name":{"first":"Will","last":"Turner"},"_id":"5e64ca6d98bbae458c82cbe3","fullName":"Will Turner","id":"5e64ca6d98bbae458c82cbe3"}

 

공식 레퍼런스: https://mongoosejs.com/docs/guide.html#virtuals

git repository: https://github.com/taeheongo/MongoDB

 

 

'Mongoose > schemas' 카테고리의 다른 글

aliases  (0) 2020.03.09
Indexes  (0) 2020.03.09
Query Helpers  (0) 2020.03.09
Statics  (0) 2020.03.09
Instance method  (0) 2020.03.09
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
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
글 보관함