[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.당신이 여기에서 찾고있는 것은 몽구스 .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 값을 적용하기 때문에 또한 당신은 여전히, 질의 또는 기타 작업을 위해 자체 모델로 각각 사용할 수 있습니다.
저장 한 컬렉션입니다하지만 그래서 많은 컬렉션을 것으로 보인다뿐만 아니라 다른 유용한 작업에 함께 유지하는 이점을 갖고 있습니다. 이것은 당신이 당신이 찾고있는 "다형성"의 종류를 적용 할 수있는 방법입니다.
from https://stackoverflow.com/questions/35468855/multiple-schema-references-in-single-schema-array-mongoose by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] 배열하여 MongoDB의 특정 필드 값으로 문서를 포함하지 않는 문서를 찾기 (0) | 2019.12.23 |
---|---|
[MONGODB] MongoDB의에서 인덱스의 크기를 추정 할 수있는 도구가 있습니까? (0) | 2019.12.23 |
[MONGODB] 이름을 일치하는 배열 요소의 MongoDB를 2.1 집계 프레임 워크 합 (0) | 2019.12.23 |
[MONGODB] MongoDB를 제한 메모리 (0) | 2019.12.23 |
[MONGODB] 설정 MongoDB의 프로그래밍 컨버터 (0) | 2019.12.23 |