복붙노트

[MONGODB] 하나의 스키마 배열에 여러 스키마 참조 - 몽구스

MONGODB

하나의 스키마 배열에 여러 스키마 참조 - 몽구스

당신은 몇 가지 스키마 옵션에 대한 참조와 몽구스 스키마의 배열을 채울 수 있습니까?

문제를 조금 명확히하기 위해, 나는 다음과 같은 스키마를 가지고 말 :

var scenarioSchema = Schema({
  _id     : Number,
  name    : String,
  guns : []
});

var ak47 = Schema({
  _id     : Number
  //Bunch of AK specific parameters
});

var m16 = Schema({
  _id     : Number
  //Bunch of M16 specific parameters
});

나는 k-47 또는 M16의 무리와 함께 총 배열을 채울 수 있습니까? 나는 같은 총 배열의 두 할 수 있나요? 아니면 하나의 특정 유형에 제한이 같은 자산의 배열에 채우기 심판을 필요로 하는가?

guns: [{ type: Schema.Types.ObjectId, ref: 'm16' }]

난 그냥 다른 건 유형에 대해 별도의 배열을 가질 수 알고 있지만 그로드 된 시나리오에 따라 비어 될 대부분의 프로젝트 규모, 같은 스키마에 추가 필드의 미친 양을 만듭니다.

var scenarioSchema = Schema({
  _id     : Number,
  name    : String,
  ak47s : [{ type: Schema.Types.ObjectId, ref: 'ak47' }],
  m16s: [{ type: Schema.Types.ObjectId, ref: 'm16' }]
});

질문에 다시 그래서, 나는 하나의 배열에 여러 스키마 참조를 부착 할 수 있습니까?

해결법

  1. ==============================

    1.당신이 여기에서 찾고있는 것은 몽구스 .discriminator () 방법이다. 이것은 기본적으로 같은 컬렉션의 서로 다른 유형의 객체를 저장하지만, 구별 할 첫 번째 클래스 객체로를 가질 수 있습니다.

    당신이 여기에서 찾고있는 것은 몽구스 .discriminator () 방법이다. 이것은 기본적으로 같은 컬렉션의 서로 다른 유형의 객체를 저장하지만, 구별 할 첫 번째 클래스 객체로를 가질 수 있습니다.

    여기에 "같은 수집"원칙 .populate ()가 작동하고 포함하는 모델의 참조의 정의 방법에 중요합니다. 당신은 정말에만 어쨌든 참조 "하나"모델을 가리킬 수 있지만, 하나 개의 모델이 많은으로 표시 할 수있는 몇 가지 다른 마법가 있기 때문에.

    예 목록 :

    var util = require('util'),
        async = require('async'),
        mongoose = require('mongoose'),
        Schema = mongoose.Schema;
    
    mongoose.connect('mongodb://localhost/gunshow');
    
    //mongoose.set("debug",true);
    
    var scenarioSchema = new Schema({
      "name": String,
      "guns": [{ "type": Schema.Types.ObjectId, "ref": "Gun" }]
    });
    
    function BaseSchema() {
      Schema.apply(this, arguments);
    
      // Common Gun stuff
      this.add({
        "createdAt": { "type": Date, "default": Date.now }
      });
    }
    
    util.inherits(BaseSchema, Schema);
    
    var gunSchema = new BaseSchema();
    
    var ak47Schema = new BaseSchema({
      // Ak74 stuff
    });
    
    ak47Schema.methods.shoot = function() {
      return "Crack!Crack";
    };
    
    var m16Schema = new BaseSchema({
      // M16 Stuff
    });
    
    m16Schema.methods.shoot = function() {
      return "Blam!!"
    };
    
    
    var Scenario = mongoose.model("Scenario", scenarioSchema);
    
    var Gun = mongoose.model("Gun", gunSchema );
    var Ak47 = Gun.discriminator("Ak47", ak47Schema );
    var M16 = Gun.discriminator("M16", m16Schema );
    
    
    async.series(
      [
        // Cleanup
        function(callback) {
          async.each([Scenario,Gun],function(model,callback) {
            model.remove({},callback);
          },callback);
        },
    
        // Add some guns and add to scenario
        function(callback) {
          async.waterfall(
            [
              function(callback) {
                async.map([Ak47,M16],function(gun,callback) {
                  gun.create({},callback);
                },callback);
              },
              function(guns,callback) {
                Scenario.create({
                  "name": "Test",
                  "guns": guns
                },callback);
              }
            ],
            callback
          );
        },
    
        // Get populated scenario
        function(callback) {
          Scenario.findOne().populate("guns").exec(function(err,data) {
    
            console.log("Populated:\n%s",JSON.stringify(data,undefined,2));
    
            // Shoot each gun for fun!
            data.guns.forEach(function(gun) {
              console.log("%s says %s",gun.__t,gun.shoot());
            });
    
            callback(err);
          });
        },
    
        // Show the Guns collection
        function(callback) {
          Gun.find().exec(function(err,guns) {
            console.log("Guns:\n%s", JSON.stringify(guns,undefined,2));
            callback(err);
          });
        },
    
        // Show magic filtering
        function(callback) {
          Ak47.find().exec(function(err,ak47) {
            console.log("Magic!:\n%s", JSON.stringify(ak47,undefined,2));
            callback(err);
          });
        }
      ],
      function(err) {
        if (err) throw err;
        mongoose.disconnect();
      }
    );
    

    그리고 출력

    Populated:
    {
      "_id": "56c508069d16fab84ead921d",
      "name": "Test",
      "__v": 0,
      "guns": [
        {
          "_id": "56c508069d16fab84ead921b",
          "__v": 0,
          "__t": "Ak47",
          "createdAt": "2016-02-17T23:53:42.853Z"
        },
        {
          "_id": "56c508069d16fab84ead921c",
          "__v": 0,
          "__t": "M16",
          "createdAt": "2016-02-17T23:53:42.862Z"
        }
      ]
    }
    Ak47 says Crack!Crack
    M16 says Blam!!
    Guns:
    [
      {
        "_id": "56c508069d16fab84ead921b",
        "__v": 0,
        "__t": "Ak47",
        "createdAt": "2016-02-17T23:53:42.853Z"
      },
      {
        "_id": "56c508069d16fab84ead921c",
        "__v": 0,
        "__t": "M16",
        "createdAt": "2016-02-17T23:53:42.862Z"
      }
    ]
    Magic!:
    [
      {
        "_id": "56c508069d16fab84ead921b",
        "__v": 0,
        "__t": "Ak47",
        "createdAt": "2016-02-17T23:53:42.853Z"
      }
    ]
    

    또한이 몽구스가 실제로 호출을 구성하는 방법을 볼 수 목록에서 mongoose.set ( "디버그", true)를 행의 주석을 해제 할 수 있습니다.

    그래서이 보여주는 것은 당신이 다른 첫 번째 클래스 개체를 다른 스키마를 적용하고, 심지어는 단지 실물처럼 연결된 다른 방법으로 할 수 있다는 것입니다. 몽구스는 첨부 된 모델은 "총"컬렉션이 모두 저장되며,이 판별에 의해 refernced 모든 "유형"이 포함됩니다 :

    var Gun = mongoose.model("Gun", gunSchema );
    var Ak47 = Gun.discriminator("Ak47", ak47Schema );
    var M16 = Gun.discriminator("M16", m16Schema );
    

    그러나 각 다른 "유형"특별한 방법으로 자신의 모델로 참조됩니다. 당신이 그 몽구스 저장을보고 객체를 읽어 그래서, 적용, 따라서 스키마를 부착 할 수있는 "모델"을 알려주는 특별한 __t 필드가있다.

    하나의 예를 들어 우리는 각 모델 / 스키마에 대해 다르게 정의 된 .shoot () 메소드를 호출합니다. AK47은 자동으로 모든 쿼리 / upates에 __t 값을 적용하기 때문에 또한 당신은 여전히, 질의 또는 기타 작업을 위해 자체 모델로 각각 사용할 수 있습니다.

    저장 한 컬렉션입니다하지만 그래서 많은 컬렉션을 것으로 보인다뿐만 아니라 다른 유용한 작업에 함께 유지하는 이점을 갖고 있습니다. 이것은 당신이 당신이 찾고있는 "다형성"의 종류를 적용 할 수있는 방법입니다.

  2. from https://stackoverflow.com/questions/35468855/multiple-schema-references-in-single-schema-array-mongoose by cc-by-sa and MIT license