マングースを使用すると、おそらくここに行くことができます。discriminators実際には、格納されたドキュメント内の独自の "タイプ"(デフォルトでは、__t
のプロパティ)で動作します。これにより、マングースは、それぞれのオブジェクトに独自の添付されたスキーマを持つ一種の "モデル"を実際に適用できます。簡単な例として
:これらは基本的にしているので、だから、「関連」
var async = require('async'),
util = require('util'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/things');
mongoose.set("debug",true);
function BaseSchema() {
Schema.apply(this,arguments);
this.add({
key: String,
created_at: { type: Date, default: Date.now }
});
}
util.inherits(BaseSchema,Schema);
var metaSchema = new BaseSchema();
var stringSchema = new BaseSchema({
value: String
});
var numberSchema = new BaseSchema({
value: Number
});
var dateSchema = new BaseSchema({
value: Date
});
var MetaModel = mongoose.model('MetaModel',metaSchema),
StringModel = MetaModel.discriminator('StringModel', stringSchema),
NumberModel = MetaModel.discriminator('NumberModel', numberSchema),
DateModel = MetaModel.discriminator('DateModel', dateSchema);
async.series(
[
function(callback) {
MetaModel.remove({},callback);
},
function(callback) {
async.each(
[
{ "model": "StringModel", "value": "Hello" },
{ "model": "NumberModel", "value": 12 },
{ "model": "DateModel", "value": new Date() }
],
function(item,callback) {
mongoose.model(item.model).create(item,callback)
},
callback
);
},
function(callback) {
MetaModel.find().exec(function(err,docs) {
console.log(docs);
callback(err);
});
},
function(callback) {
DateModel.findOne().exec(function(err,doc) {
console.log(doc);
callback(err);
});
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
)
は、私は、共通の要素を持つ「ベース」スキーマを定義しています。もちろん、それぞれの "タイプ"ごとに別々のスキーマがあります。コア「モデル」への実際の割り当ては、これらの行で発生します:
var MetaModel = mongoose.model('MetaModel',metaSchema),
StringModel = MetaModel.discriminator('StringModel', stringSchema),
NumberModel = MetaModel.discriminator('NumberModel', numberSchema),
DateModel = MetaModel.discriminator('DateModel', dateSchema);
これはMetaModel
が実際に収集し、「デフォルト」のスキーマのassingmentを定義することを意味します。次の行は、同じコレクションに格納されるドキュメントの他の "タイプ"を定義するために、そのモデルの.discriminator()
を使用しています。参照するときしかし、あなたはそのすべてがメインモデルに割り当てられmetamodels
コレクションに作成されて見ることができます
Mongoose: metamodels.remove({}) {}
Mongoose: metamodels.insert({ value: 'Hello', __t: 'StringModel', created_at: new Date("Thu, 07 Apr 2016 00:24:08 GMT"), _id: ObjectId("5705a8a8443c0f74491bdec0"), __v: 0 })
Mongoose: metamodels.insert({ value: 12, __t: 'NumberModel', created_at: new Date("Thu, 07 Apr 2016 00:24:08 GMT"), _id: ObjectId("5705a8a8443c0f74491bdec1"), __v: 0 })
Mongoose: metamodels.insert({ value: new Date("Thu, 07 Apr 2016 00:24:08 GMT"), __t: 'DateModel', created_at: new Date("Thu, 07 Apr 2016 00:24:08 GMT"), _id: ObjectId("5705a8a8443c0f74491bdec2"), __v: 0 })
Mongoose: metamodels.find({}) { fields: undefined }
[ { created_at: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST),
__t: 'StringModel',
__v: 0,
value: 'Hello',
_id: 5705a8a8443c0f74491bdec0 },
{ created_at: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST),
__t: 'NumberModel',
__v: 0,
value: 12,
_id: 5705a8a8443c0f74491bdec1 },
{ created_at: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST),
__t: 'DateModel',
__v: 0,
value: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST),
_id: 5705a8a8443c0f74491bdec2 } ]
Mongoose: metamodels.findOne({ __t: 'DateModel' }) { fields: undefined }
{ created_at: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST),
__t: 'DateModel',
__v: 0,
value: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST),
_id: 5705a8a8443c0f74491bdec2 }
:何が起こっているかを示すために上のデバッグ出力で
は、そのリストは、このような何かを作り出します各「識別器モデル」には、モデル名を含む__t
フィールドが自動的に作成されます。これは後でデータを読み込む際に使用され、mongooseはオブジェクトをキャストするときに適用するモデルとアタッチされたスキーマを認識します。
これらはすべて独自のスキーマを持つため、標準の検証ルールが適用されます。さらに、各タイプのスキーマに付加された「インスタンスメソッド」も、別個のモデルと同じように適用されます。
最後に、その__t
フィールドは、クエリや更新などの他の操作に「ディスクリミネータモデル」の1つを使用して適用されます。
DateModel.findOne().exec(function(err,doc) {
console.log(doc);
callback(err);
});
そして、実際の呼び出し:最後に実行されたステートメントに示すように
Mongoose: metamodels.findOne({ __t: 'DateModel' }) { fields: undefined }
プロパティの値は、「タイプ」を示し、収集データの「仮想ビュー」を与えるために自動的に含まれていることまるでその特定のタイプだけを含んでいるかのように。
実際のパワーは、同じコレクション内のすべてのオブジェクトにあり、マングースがデータの取得時に自動的に「クラスタイプ」を割り当てることができます。
これを処理するより良い方法は[discriminators](http://mongoosejs.com/docs/discriminators.html)です。これは本質的に各オブジェクトをバインドさせる独自の "タイプ"(デフォルトは '__t')を実装しますそれ自身の擬似モデルであり、それ自身のスキーマです。次に、各 "タイプ"に対して "厳密な"処理を行うことができます。これは、「混合」を使用する場所で検証ロジックを手作業で行うよりもはるかに優れています。 –
ありがとう@NeilLunn!これは私の必要と同じように見えます。私が受け入れることができる応答を提出してインターネットポイントを増やしたいのですか? :) ありがとうございました! – Greg