ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Mongoose - 모르는 것 채워놓기
    DB/MongoDB 2017. 12. 3. 00:55

     

     

    스키마의 옵션(Schema's option)


    mongoose에서 스키마를 선언하는 과정에서 사용할 수 있는 옵션들이 존재한다.



    http://mongoosejs.com/docs/guide.html#collection

    이렇게 다양한 옵션들이 존재하는데 자세한 사항은 위 URL을 참조하자.

    id

    몽구스에서 id는 기본적으로 도큐먼트의 _id 필드를 반환하는, 각각의 스키마에 배정되는 가상의 값이다. 

    _id

    _id는 기본적으로 각각의 스키마에 배정되는 값으로, 배정되는 type같은 경우, 기본적으로 ObjectId와 일치한다. 

    위 둘의 관계에 대해서 간략하게 설명하자면, _id같은 경우 ObjectId 값을 가지며 기본적으로 할당되는 필드이다. 그리고 이 값을 참조 혹은 불러서 사용하기 위해서는 .id 의 형식으로 사용하면 된다. (_id 필드를 반환한다는 부분에 집중하자.) 

    Population



    population의 사전적 의미를 검색하면 '인구'라고 나온다. 그렇기에 population의 동사원형을 찾아보았다. 

    populate : '인구를 이동시키다'


    아하! 여기 의미를 대강 추측해 볼 수 있는데, 몽구스DB에서 Population은 다른 콜렉션에 있는 도큐먼트를 참조하는 데 사용한다고 추측해 볼 수 있다. 몽구스 홈페이지에서는 다음과 같이 설명하고 있다.


    Population은 다른 콜렉션으로부터 도큐먼트 안 특정 경로를 통해 그 부분을 도큐먼트로 자동으로 대체(치환)하는 과정이다.


    var mongoose = require('mongoose');

    var Schema = mongoose.Schema; var personSchema = Schema({ _id: Schema.Types.ObjectId, name: String, age: Number, stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }] // 리스트로 받고있는 걸 집중하자. }); var storySchema = Schema({ author: { type: Schema.Types.ObjectId, ref: 'Person' }, title: String, fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }] // 리스트로 받고있는 걸 집중하자. }); var Story = mongoose.model('Story', storySchema); var Person = mongoose.model('Person', personSchema);


    모델을 만드는 기본 구조이다. 위에서 두 개의 스키마를 만들었는데, 하나는 사람, 다른 하나는 스토리에 관한 스키마이다. 여기서 유심히 봐야할 부분은 Person의 stories와 Story의 fans는 리스트(배열)로 선언되었다는 부분이다. 이 부분은 현실을 반영해서 저렇게 구조를 설계하였다.


    위의 코드를 보면 어느 부분이 참조를 하는 영역인지 알 수 있을 것이다. 기억해야할 사항은 참조하는 프로퍼티는 타입은 ObjectId로, 그리고 ref를 이용해서 어떤 model을 참조하는 지를 표현해줘야 한다. 



    참조 저장하기(Saving refs)

    참조를 저장, 즉 참조하는 프로퍼티에 값을 할당하는 방법은 다른 프로퍼티들의 값을 저장하는 방식과 동일하다. 단지 참조하는 영역에는 _id의 값을 할당해 주면 된다.

    var author = new Person({

    _id: new mongoose.Types.ObjectId(), // default로 설정되어 있는 항목 name: 'Catnap', age: 21 }); author.save(function (err) { // save를 해줘야 값이 DB에 저장이 된다. if (err) return handleError(err); var story1 = new Story({ title: "Catnap's Love Story", author: author._id // assign the _id from the person }); story1.save(function (err) { if (err) return handleError(err); // thats it! }); });



    Populate

    populate 메소드는 그렇다면 어디에 사용하는 것일까?
    populate를 사용해야 ref에 해당 ObjectId가 속해있는 모델을 가져올 수 있는데, 즉 ObjectId에 해당하는 값과 객체를 치환해주는 역할을 해준다.

    Story.findOne({title: "Catnap's Love Story"}).populate('author').exec((err,data)=>{ // populate 사용 O
    console.log('1 : '+ data)
    })

    Story.findOne({title: "Catnap's Love Story"}).exec((err,data)=>{ // populate 사용 X
    console.log('2 : '+ data)
    })

    Story.findOne({title: "Catnap's Love Story"}).populate('author').exec((err,data)=>{ // populate 사용 O
    console.log('3 : '+ data.author.name)
    })

    Story.findOne({title: "Catnap's Love Story"}).exec((err,data)=>{ // populate 사용 X
    console.log("4 : "+ data.author.name)
    })

    위의 네 코드를 실행하면 아래와 같은 결과를 확인할 수 있다.

    1 : { _id: 5a23c1b5d52a003c98e13f1c,
      title: 'Catnap\'s Love Story',
      author:  // ObjectId가 실제 객체로 치환된 모습
       { _id: 5a23c1b5d52a003c98e13f1b,
         name: 'Catnap',
         age: 50,
         __v: 0,
         stories: [] },
      __v: 0,
      fans: [] }
    2 : { _id: 5a23c1b5d52a003c98e13f1c,
      title: 'Catnap\'s Love Story',
      author: 5a23c1b5d52a003c98e13f1b, // 여기선 ObjectId 값만 적혀있다.
      __v: 0,
      fans: [] }
    3 : Catnap
    4 : undefined

    그러니 다른 필드 참조를 제대로 사용하기 위해서는 populate 메소드를 잘 사용하는 것이 중요하다.
    이 외에도 populate를 통해 특정 도큐먼트의 한 프로퍼티만 보고 싶거나, 여러 개를 치환하는 것도 가능하다.

    이에 대한 설명은 제로초님의 블로그(https://www.zerocho.com/category/MongoDB/post/59a66f8372262500184b5363)에서 살펴보자.




     

     

    'DB > MongoDB' 카테고리의 다른 글

    MongoDB - Schema, Document  (0) 2017.11.30

    댓글

Designed by Tistory.