2012-10-25 19 views
24

मैं Mongoose.js का उपयोग करता हूं और 3 स्तर पदानुक्रम दस्तावेज़ के साथ समस्या का समाधान नहीं कर सकता।Mongoose एम्बेडेड

ऐसा करने के 2 तरीके हैं।

पहले - बिना रेफरी के।

C = new Schema({ 
    'title': String, 
}); 

B = new Schema({ 
    'title': String, 
    'c': [C] 
}); 

A = new Schema({ 
    'title': String, 
    'b': [B] 
}); 

मुझे सी रिकॉर्ड दिखाने की आवश्यकता है। मैं सी के केवल _id को जानकर, इसे कैसे ढूंढ सकता/ढूंढ सकता हूं?

मैं कोशिश उपयोग किया गया था:

A.findOne({'b.c._id': req.params.c_id}, function(err, a){ 
    console.log(a); 
}); 

लेकिन मुझे नहीं पता है कि Returnet से प्राप्त करने के लिए एक वस्तु केवल एक वस्तु को C है कि मैं की जरूरत है।

दूसरा अगर refs के साथ काम कर रहे:

C = new Schema({ 
    'title': String, 
}); 

B = new Schema({ 
    'title': String, 
    'c': [{ type: Schema.Types.ObjectId, ref: 'C' }] 
}); 

A = new Schema({ 
    'title': String, 
    'b': [{ type: Schema.Types.ObjectId, ref: 'B' }] 
}); 

कैसे सब बी को भरने के लिए, सी रिकॉर्ड पदानुक्रम पाने के लिए?

A 
.find({}) 
.populate('b') 
.populate('b.c') 
.exec(function(err, a){ 
    a.forEach(function(single_a){ 
     console.log('- ' + single_a.title); 
     single_a.b.forEach(function(single_b){ 
      console.log('-- ' + single_b.title); 
      single_b.c.forEach(function(single_c){ 
       console.log('--- ' + single_c.title); 
      }); 
     }); 
    }); 
}); 

लेकिन यह single_c.title के लिए अपरिभाषित वापस आ जाएगी:

मैं कुछ इस तरह इस्तेमाल करने की कोशिश थी। मैं इसे पॉप्युलेट करने का कोई तरीका है?

धन्यवाद।

+1

(यहां तक ​​कि विभिन्न डेटाबेस या उदाहरण में) पॉप्युलेट अब है कि इस समर्थित है एक नया स्वीकार किए जाते हैं जवाब चुनने के लिए अच्छा नहीं होगा सकते हैं। – JohnnyHK

उत्तर

24

नेवला 4 में आप अनेक स्तरों पर दस्तावेजों को पॉप्युलेट कर सकते हैं:

आप एक उपयोगकर्ता स्कीमा जो उपयोगकर्ता के दोस्तों का ट्रैक रखता है कहो।

var userSchema = new Schema({ 
    name: String, 
    friends: [{ type: ObjectId, ref: 'User' }] 
}); 

populate() आपको उपयोगकर्ता के दोस्तों की एक सूची प्राप्त करने देता है। लेकिन क्या होगा यदि आप उपयोगकर्ता के दोस्तों के दोस्तों को भी चाहते थे? निर्दिष्ट करें सभी उपयोगकर्ता के दोस्तों का friends सरणी को भरने के लिए नेवला बताने के लिए populate विकल्प:

User. 
    findOne({ name: 'Val' }). 
    populate({ 
    path: 'friends', 
    // Get friends of friends - populate the 'friends' array for every friend 
    populate: { path: 'friends' } 
    }); 

से लिया: http://mongoosejs.com/docs/populate.html#deep-populate

+0

इसी तरह के प्रश्न http://stackoverflow.com/q/11137239/728287 –

+2

FYI - यह संस्करण 3.6 में हल किया गया है - https://github.com/LearnBoost/mongoose/wiki/3.6-Release -नोट्स – BoxerBucks

+0

@ बॉक्सरबक्स क्या आप एक उदाहरण प्रदान कर सकते हैं? (रेफरी के साथ मामला) – fusio

41

एक प्रश्न में नेवला 3.6 the ability to recursively populate related documents के रूप में जोड़ा गया है। यहाँ कैसे आप यह कर सकते हैं का एक उदाहरण है:

UserList.findById(listId) 
     .populate('refUserListItems') 
     .exec(function(err, doc){ 
      UserListItem.populate(doc.refUserListItems, {path:'refSuggestion'}, 
        function(err, data){ 
         console.log("User List data: %j", doc); 
         cb(null, doc); 
        } 
      );  
      });   

इस मामले में, मैं उनके संदर्भित दस्तावेजों के साथ 'refUserListItems' में पहचान-पत्र की एक सरणी को आबाद करने कर रहा हूँ। क्वेरी का नतीजा तब एक और आबादी वाले प्रश्न में पारित हो जाता है जो मूल आबादी वाले दस्तावेज़ के क्षेत्र को संदर्भित करता है जिसे मैं पॉप्युलेट करना चाहता हूं - 'refSuggestion'।

दूसरा (आंतरिक) जनसंख्या नोट करें - यह वह जगह है जहां जादू होता है। आप इन पॉप्युलेट्स को घोंसला जारी रख सकते हैं और अधिक से अधिक दस्तावेज़ों पर तब तक काम कर सकते हैं जब तक कि आपने अपना ग्राफ जिस तरह से बनाया हो, उसे बनाया हो।

यह पचाने में थोड़ा समय लगता है कि यह कैसे काम कर रहा है, लेकिन यदि आप इसके माध्यम से काम करते हैं, तो यह समझ में आता है।

+0

निश्चित रूप से! धन्यवाद :) – fusio

+0

यह काम करता है, लेकिन ऊपर Buu Nguyen द्वारा दी गई गहरी आबादी, अधिक सुविधाजनक है। नेस्टेड लूप करने की कोई ज़रूरत नहीं है .. –

+0

मैं वादे का उपयोग करके यह कैसे कर सकता हूं? – steampowered

4

मुझे देर हो चुकी है, लेकिन मैंने Mongoose plugin लिखा है जो गहरी मॉडल आबादी को निष्पादित करना बेहद आसान बनाता है। , इस तरह

A.find({}, function (err, docs) { 
    A.deepPopulate(docs, 'b.c', cb) 
} 

तुम भी आबादी वाले रास्तों में से प्रत्येक के लिए Mongoose populate options निर्दिष्ट कर सकते हैं: बाहर प्लगइन documentation अधिक के लिए

A.deepPopulate(docs, 'b.c', { 
    b: { 
    select: 'name' 
    } 
}, cb) 

चेक आपके उदाहरण के लिए, आप इस को भरने के लिए b और c कर सकते हैं जानकारी।

+0

निष्पादित करने की आवश्यकता क्यों नहीं है यह वास्तव में अच्छा लगता है। जब मैं अधिक परिपक्व हो जाता हूं तो मैं इसे उत्पादन में उपयोग कर सकता हूं। – steampowered

+0

बी नहीं है: एक सी होने का मतलब है? –

27

नेवला 4 में आप इस तरह बहुस्तरीय

A 
.find({}) 
.populate({ 
    path: 'b', 
    model: 'B', 
    populate: { 
    path: 'c', 
    model: 'C' 
    } 
}) 
.exec(function(err, a){}); 
+8

यह निश्चित रूप से सही उत्तर +1 –

+0

के रूप में चिह्नित किया जाना चाहिए यह केवल नए संस्करण में उपलब्ध है, इसलिए ... –

+3

यह सही उत्तर होना चाहिए। +1 – CENT1PEDE