2013-08-14 2 views
16

मैं निम्नलिखित दस्तावेज़ स्कीमा है:एक mongoose स्कीमा में 'वर्चुअल' चर जोड़ना?

var pageSchema = new Schema({ 
     name: String 
    , desc: String 
    , url: String 
}) 

अब, अपने आवेदन में मैं भी वस्तु के अंदर पेज के HTML स्रोत चाहते हैं, लेकिन मैं DB में संग्रहीत करने के लिए नहीं करना चाहती।

क्या मुझे एक "स्थानीय" वर्धित ऑब्जेक्ट बनाना चाहिए जिसमें डीबी दस्तावेज़ का संदर्भ हो?

function Page (docModel, html) { 
    this._docModel = docModel 
    this._html = html 
} 

क्या "वर्चुअल" फ़ील्ड जोड़कर सीधे दस्तावेज़ मॉडल का उपयोग करने का कोई तरीका है?

+0

आप इसे ऑब्जेक्ट में क्यों रखना चाहते हैं लेकिन इसे स्टोर नहीं करना चाहते हैं? –

+0

क्योंकि मुझे लगातार रहने की आवश्यकता नहीं है: अगर मैं अपने सर्वर को रीबूट करता हूं और डेटाबेस से ऑब्जेक्ट को पुनः लोड करता हूं, तो उस HTML को भी अपडेट करने की आवश्यकता होगी (यह बाहरी प्रक्रिया से आता है)। मैं इसे स्टोर कर सकता था, लेकिन यह बर्बाद जगह होगी। चूंकि मोंगोस में वर्चुअल विधियां हैं, तो वर्चुअल वेरिएबल्स भी अच्छा रहेगा .. – fusio

+1

आप ऑब्जेक्ट पर 'document.prop = html' जैसे किसी प्रॉपर्टी को सेट कर सकते हैं। मुझे नहीं लगता कि विधि या वर्चुअल वास्तव में आपको "स्थानीय" डेटा लाने देंगे यदि आप ऑब्जेक्ट को डीबी से फिर से प्राप्त करते हैं, भले ही पुनरारंभ नहीं हो रहा हो। –

उत्तर

32

यह मोन्गोज़ में पूरी तरह से संभव है।
चेक इस उदाहरण, अपनी दस्तावेज़ीकरण से लिया:

var personSchema = new Schema({ 
    name: { 
    first: String, 
    last: String 
    } 
}); 

personSchema.virtual('name.full').get(function() { 
    return this.name.first + ' ' + this.name.last; 
}); 
console.log('%s is insane', bad.name.full); // Walter White is insane 

उपरोक्त उदाहरण में, संपत्ति एक सेटर नहीं होगा। इस आभासी के लिए एक सेटर करवाने के लिए, ऐसा करते हैं:

personSchema.virtual('name.full').get(function() { 
    return this.name.full; 
}).set(function(name) { 
    var split = name.split(' '); 
    this.name.first = split[0]; 
    this.name.last = split[1]; 
}); 

Documentation

+2

हां लेकिन वे नए फ़ील्ड नहीं जोड़ रहे हैं .. वे मौजूदा लोगों का उपयोग कर रहे हैं। – fusio

+1

और समस्या क्या है? आप सेटर्स का भी उपयोग कर सकते हैं। – gustavohenke

+0

ओह, मैं देखता हूं। आपका मतलब है कि मुझे वर्चुअल 'सेट' के अंदर' this.newfield = 'होना चाहिए। – fusio

11

मैं वास्तव में इस परीक्षण नहीं किया लेकिन यह विचार योग्य लगता है:

//model 
var pageSchema = new Schema({ 
     name: String 
    , desc: String 
    , url: String 
}) 

pageSchema.virtual('html') 
    .get(function(){ 
    var url = this.url 

    function get(url) { 
     return new (require('httpclient').HttpClient)({ 
     method: 'GET', 
      url: url 
     }).finish().body.read().decodeToString(); 
    } 

    return get(url); 
    }); 


    //controller 
    var page = new Page({ 
    name: "Google" 
    , desc: "Search engine" 
    , url: "http://google.com" 
    }); 

    var html = page.html; 

मूल रूप से एक आभासी विशेषता html बुलाया सेट जो शरीर को url विशेषता के लिए अनुरोध करता है और इसे वापस करता है।

यदि आप एक्सप्रेस और res.send(page) का उपयोग कर रहे हैं तो toJSON के लिए वर्चुअल विशेषताओं के आउटपुट को सक्षम करना सुनिश्चित करें।

pageSchema.set('toJSON', { 
    virtuals: true 
}); 
12

दस्तावेज़ गुण है कि __ के साथ शुरू करने के लिए डाटाबेस कायम नहीं कर रहे हैं, तो आप एक आभासी संपत्ति बना सकते हैं और गेटर और सेटर उपयोग this.__html

pageSchema.virtual('html').get(function() { 
    return this.__html; 
}).set(function (html) { 
    this.__html = html; 
}); 

हो सकता था, लेकिन यह एक हैक का एक सा है एक चेतावनी के साथ: इस कार्यक्षमता को दस्तावेज नहीं किया गया है, इसलिए __ से शुरू होने वाली आंतरिक गुणों की कोई सूची नहीं है, इसलिए संभावना है कि भविष्य में आंतरिक कार्यान्वयन __html

नामक एक var का उपयोग शुरू कर सकता है

https://github.com/Automattic/mongoose/issues/2642

संबंधित मुद्दे