जो आप यहां देख रहे हैं वह mongoose .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("debug",true)
लाइन सूची में कैसे नेवला वास्तव में कॉल निर्माण कर रही है को देखने के लिए uncomment कर सकते हैं।
तो यह दर्शाता है कि आप विभिन्न प्रथम श्रेणी वस्तुओं के लिए अलग-अलग स्कीमा लागू कर सकते हैं, और यहां तक कि असली वस्तुओं की तरह उनके साथ जुड़े विभिन्न तरीकों के साथ भी। नेवला सभी संलग्न मॉडल के साथ एक "बंदूकों" संग्रह में इन भंडारण है, और यह सब "प्रकार" discriminator द्वारा refernced में शामिल होंगे:
var Gun = mongoose.model("Gun", gunSchema);
var Ak47 = Gun.discriminator("Ak47", ak47Schema);
var M16 = Gun.discriminator("M16", m16Schema);
लेकिन यह भी प्रत्येक अलग "प्रकार" में उसके अपने मॉडल के साथ संदर्भित है एक विशेष तरीका तो आप देखते हैं कि जब मोंगोज़ ऑब्जेक्ट को स्टोर करता है और पढ़ता है, तो एक विशेष __t
फ़ील्ड होता है जो बताता है कि कौन सा "मॉडल" लागू करना है, और इसलिए स्कीमा संलग्न है।
एक उदाहरण के रूप में हम .shoot()
विधि को कॉल करते हैं, जिसे प्रत्येक मॉडल/स्कीमा के लिए अलग-अलग परिभाषित किया जाता है। और आप अभी भी प्रश्नों या अन्य परिचालनों के लिए मॉडल के रूप में प्रत्येक का उपयोग कर सकते हैं, क्योंकि Ak47
स्वचालित रूप से सभी क्वेरी/अपेट्स में __t
मान लागू करेगा।
हालांकि स्टोरेज एक संग्रह में है, लेकिन यह कई संग्रह प्रतीत होता है, लेकिन उन्हें अन्य उपयोगी संचालन के लिए एक साथ रखने का लाभ भी है। इस प्रकार आप "पॉलिमॉर्फिज्म" की तरह आवेदन कर सकते हैं जिसे आप ढूंढ रहे हैं।
वाह जो सुपर सूचनात्मक था! धन्यवाद!! – BrentShanahan