• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

안녕하세요. 질문드리고 싶은 부분이 있습니다.

21.06.09 11:03 작성 조회수 220

1

항상 좋은 강의해주셔서 감사합니다! 

스키마 구조 설계에 관한 궁금증이 생겼습니다.

몽고DB의  schemaless 의 특징 때문에 유동저으로 Data를 저장할 수 있다고 알고 있습니다.

만약 Model의 스키마 구조가 이렇게 되어있다고 할 때 value로 들어오는 값이 정해져 있지 않을 때 내장해서 관리하고 싶은데 혹시 방법이 있는지 궁금합니다. value의 값으로 들어올 수 있는 것은 json 객체이며 { a:3 }이 들어올 수 있고 {b: 'ok'} 등 다양한 data가 들어올 수 있습니다.  이런식으로 정해져있지 않은 값을 내장할 수 있는지.. 그리고 방법이 궁금합니다!

실제로 value: Object 이렇게 하면 그냥 모든 데이터든 들어가는 것 같은데.. 먼가 이렇게 하면 안될 것 같은 느낌이라.. 현업에서는 이럴 경우 어떻게 구조를 짜시는지 궁금합니다.

{
    name: string,
    age : number,
    value: 구조가 다양함
}

답변 1

답변을 작성해보세요.

1

우동이님 안녕하세요 :)

네 일단 몽고디비상으로는 말씀하신게 당연히 가능합니다. Mongoose에서 이게 가능하냐가 문제인데 몽구스에서 세자기 방법이 있는거 같아요.

몽구스에 보면 Mixed 타입이 있어요. value : { type: Mixed } 이렇게 해주시면 value에 원하는 객체를 자유롭게 저장할 수 있어 보입니다. 또 다른 방법으로는  새로운 스키마를 내장하는건데요. 다음과 같이 옵션을 주면 되네요. value : new Schema({}, { strict: false })

위 답변은 stackoverflow 답변을 참고해서 작성했습니다.

근데 더 좋아 보이는 방법으로는 mongoose의 discriminator라는 기능을 사용하는거 같아요. 완전 자유롭게 내장하는게 아니고 여러 자식문서의 schema를 enum으로 제공해주는 방식이에요. 아래 보시면 evenSchema는 message라는 필드를 공통으로 가지고 있고요. kind의 필드로 서로 다른 자식 문서 타입을 구분하고 있어요. 제가 알기로 kind를 따로 설정하지 않으면 _t라는 키가 자동 생성되요. 그 외 events안에 들어가는 내용은 각각 다르게 구성할 수 있어요. 완전한 자유보다는 이런식으로 하는게 더 좋지 않을까 싶어요. 그래야 데이터를 불러드렸을 때 사용이 가능하지 않을까 싶습니다. 아래 예시 코드는 깃헙 질문에서 가져왔어요. 공식문서도 확인해보시면 좋을거 같아요.

var eventSchema = new Schema({ message: String },
  { discriminatorKey: 'kind', _id: false });

var batchSchema = new Schema({ events: [eventSchema] });
batchSchema.path('events').discriminator('Clicked', new Schema({
  element: String
}, { _id: false }));
batchSchema.path('events').discriminator('Purchased', new Schema({
  product: String
}, { _id: false }));

var MyModel = db.model('gh2723', batchSchema);
var doc = {
  events: [
    { kind: 'Clicked', element: 'Test' }, // 여기는 element필드가 존재하고
    { kind: 'Purchased', product: 'Test2' } //여기에는 product필드가 존재합니다
  ]
};
MyModel.create(doc).
  then(function(doc) {
    // doc.events[0] has an 'element' property, doc.events[1] has a 'product' property
  });