2011-10-30 16 views
5

मैं नेवला उपयोग कर रहा हूँ Person और Transaction संग्रह है, जहां प्रत्येक Transaction दो अलग Person उदाहरणों के लिए संदर्भ होगा मॉडल करने के लिए:मोंगोस: विदेशी कुंजी/व्यस्त संबंध कैसे मॉडल करें?

var TransactionSchema = new Schema({ 
    , amount   : { type: Number, required: true } 
    , from   : { type: ObjectId, required: true } 
    , to    : { type: ObjectId, required: true } 
    , date   : Date 
}); 

var PersonSchema = new Schema({ 
    name   : { type: String, required: true } 
    , transactions : [ObjectId] 
}); 

मैं हर Person चाहते हैं सभी Transaction रों वे कर रहे हैं कि का एक संग्रह के लिए या तो to या from के लिए मूल्य। अब तक, यह सबसे अच्छा तरीका है कि मैं इसे कैसे समझ सकता हूं:

TransactionSchema.pre('save', function(next, done) { 
    var transaction = this; 

    Person.findById(this.to, function (err, person) { 
     person.transactions.push(transaction); 
     person.save(); 
    }); 

    Person.findById(this.from, function (err, person) { 
     person.transactions.push(transaction); 
     person.save(); 
    }); 

    next(); 
}); 

यह अत्यधिक लगता है। क्या ऐसा करने का कोई बेहतर तरीका है, या क्या मैं मोंगो डीबी का उपयोग एक रिलेशनल डेटाबेस की तरह करने की कोशिश कर रहा हूं? इसके बजाय प्रत्येक Person उदाहरण के साथ जुड़े Transaction रों का एक संग्रह होने का, मैं सिर्फ सीधे Translation संग्रह की क्वेरी किया जाना चाहिए?

धन्यवाद।

उत्तर

7

आप प्रश्नों आप डेटाबेस पर अमल करने के लिए जब आप MongoDB स्कीमा डिजाइन जा रहे हैं के बारे में अधिक सोचने के लिए मिल गया है।

गति के लिए डेटा नकल और अखंडता के लिए इसे संदर्भ की कोशिश करें। इसका क्या मतलब है?
ठीक है, उदाहरण के लिए जब आप लेनदेन के लिए कोई प्रश्न पूछते हैं, तो मुझे लगता है कि आपको पहली बार सभी उपयोगकर्ता विवरणों की आवश्यकता नहीं है? (आप जब किसी लेन-देन के बारे में जानकारी प्रदर्शित उपयोगकर्ता के ईमेल, स्थान की आवश्यकता है?)
मुझे लगता है कि तुम सिर्फ शायद प्रयोक्ता आईडी और उपयोगकर्ता नाम की आवश्यकता है, तो आप कुछ इस तरह करना चाहिए: तो बजाय

var TransactionSchema = new Schema({ 
    , amount   : { type: Number, required: true } 
    , from   : { 
    user_id: { 
     type: ObjectId 
    , required: true 
    } 
    , username: { 
     type: String 
    , required: true 
    } 
    } 
    , to    : { 
    user_id: { 
     type: ObjectId 
    , required: true 
    } 
    , username: { 
     type: String 
    , required: true 
    } 
    } 
    , date   : Date 
}); 

लेनदेन विवरण (लेनदेन के लिए एक और उपयोगकर्ता नामों के लिए 2 अतिरिक्त प्रश्न) प्रदर्शित करने वाले पृष्ठ के लिए 3 प्रश्न करने के लिए, आपके पास केवल एक होगा।
यह केवल एक उदाहरण है, आप जो भी हासिल करने की कोशिश कर रहे हैं उसके आधार पर आप उपयोगकर्ता स्कीमा के लिए एक ही तर्क लागू कर सकते हैं।

वैसे भी मुझे नहीं लगता कि आपका मिडलवेयर ठीक है, क्योंकि आप वहां त्रुटियों की जांच नहीं कर रहे हैं (आप हमेशा अगली बात कर रहे हैं इससे कोई फर्क नहीं पड़ता)। यह मैं कैसे मिडलवेयर लिखना होता है (परीक्षण नहीं किया था, लेकिन यह विचार महत्वपूर्ण है): ऊपर मैं प्रवाह नियंत्रण के लिए Step पुस्तकालय का उपयोग कर रहा

TransactionSchema.pre('save', function(next, done) { 
    var transaction = this; 

    Person.where('_id').in([this.to, this.from]).run(function (err, people) { 
    if (people.length != 2) { next(new Error("To or from doesn't exist")); return; } 
    Step(
     function save_to() { 
     people[0].transactions.push(transaction); 
     people[0].save(this); 
     }, 
     function save_from(err) { 
     if (err) { next(err); return; } 
     people[1].transactions.push(transaction); 
     people[1].save(this); 
     }, 
     function callback(err) { 
     next(err); 
     } 
    ); 
    }); 
}); 

कोड में और मैं केवल एक क्वेरी का उपयोग कर रहा दो की बजाय (जब "से" और "से" खोज रहे हैं)।

+0

muchos! बस मुझे –

+0

पढ़ने की आवश्यकता है क्या यह पूर्व-सहेजने या पोस्ट-सेव में ऐसा करना बेहतर है। यदि सत्यापन त्रुटियों या किसी अन्य त्रुटि के कारण लेनदेन सहेजा नहीं गया है तो क्या होगा। क्या आपने अभी व्यक्ति में डमी आइटम नहीं जोड़ा होगा? यदि आप पोस्ट-सेव में ऐसा करते हैं तो आपको लेनदेन के लिए फिर से पूछना नहीं होगा – raju

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