2013-10-30 7 views
8

मैं मोंगो डीबी का उपयोग नोडजेस आरईएसटी सेवा के साथ कर रहा हूं जो मेरे डेटा को अंदर संग्रहीत करता है। मेरे पास एक प्रश्न है कि मेरे डेटा से पूछताछ कैसे करें जो $ ref का उपयोग करता है।

यहाँ एक वस्तु है जो एक परागकोष संग्रह में एक और वस्तु (विस्तार) के लिए संदर्भ शामिल हैं का एक नमूना है:

{ 
    "_id" : ObjectId("5962c7b53b6a02100a000085"), 
    "Title" : "test", 
    "detail" : { 
     "$ref" : "ObjDetail", 
     "$id" : ObjectId("5270c7b11f6a02100a000001") 
    }, 
    "foo" : bar 
} 

वास्तव में, Node.js और MongoDB मॉड्यूल का उपयोग कर, मैं निम्नलिखित है:

db.collection("Obj").findOne({"_id" : new ObjectID("5962c7b53b6a02100a000085"}, 
function(err, item) { 
    db.collection(item.$ref).findOne({"_id" : item.$id}, function(err,subItem){ 
     ... 
    }); 
}); 

वास्तव में मैं 2 प्रश्न करता हूं, और 2 ऑब्जेक्ट प्राप्त करता हूं। यह एक प्रकार का "आलसी लोडिंग" (बिल्कुल नहीं बल्कि लगभग)

मेरा प्रश्न सरल है: क्या एक ऑब्जेक्ट ग्राफ़ को एक क्वेरी में पुनर्प्राप्त करना संभव है?

धन्यवाद

उत्तर

1

व्लादिमीर का जवाब अभी भी मान्य नहीं है के रूप में db.dereference विधि MongoDB NodeJS एपीआई से हटा दिया गया:

https://www.mongodb.com/blog/post/introducing-nodejs-mongodb-20-driver

डाटाबेस उदाहरण वस्तु को सरल बनाया गया है। हम निम्न विधियों में निकाल दिया है: संदर्भ db के कारण

db.dereference सर्वर

4

नहीं, आप नहीं कर सकते।

डीबीआरएफ को हल करने के लिए, आपके आवेदन को संदर्भित दस्तावेज़ों को वापस करने के लिए अतिरिक्त प्रश्नों को निष्पादित करना होगा। कई ड्राइवरों में सहायक विधियां होती हैं जो स्वचालित रूप से DBRef के लिए क्वेरी बनाती हैं। ड्राइवर स्वचालित रूप से दस्तावेजों में डीबीआरआईएफ को हल नहीं करते हैं।

मोंगोडीबी दस्तावेज़ http://docs.mongodb.org/manual/reference/database-references/ से।

+1

और जहाँ तक में पदावनत किया जा रहा के रूप में मैं जानता हूँ कि नोड MongoDB देशी चालक इन को हल करने के लिए एक रास्ता नहीं है आपके लिए रेफरी – Brett

4

क्या सिंगल मोंगोडीबी क्वेरी का उपयोग करके पेरेंट ऑब्जेक्ट को इसके $ ref के साथ लाने के लिए संभव है?

नहीं, यह संभव नहीं है। मोंगो के पास रेफरी के लिए कोई आंतरिक समर्थन नहीं है, इसलिए यह आपके आवेदन पर निर्भर करता है (Brett's answer देखें)।

लेकिन क्या यह मूल वस्तु को अपने सभी रेफरी के साथ एक एकल node.js कमांड के साथ लाने के लिए संभव है?

हां, यह संभव है। आप इसे Mongoose के साथ कर सकते हैं। इसमें रेफरी की आबादी का समर्थन है। इसे काम करने के लिए आपको अपना डेटा मॉडल थोड़ा सा बदलना होगा, लेकिन यह वही है जो आप खोज रहे हैं। बेशक, ऐसा करने के लिए मोंगोस वही दो मोंगोडीबी प्रश्न पूछेंगे जो आपने किया था।

1

नहीं, मोंगो डीबी के लिए बहुत कम ड्राइवरों में DBRef के लिए विशेष समर्थन शामिल है। दो कारण हैं:

  1. मोंगो डीबी के पास संदर्भित दस्तावेजों को पुनर्प्राप्त करने के लिए कोई विशेष आदेश नहीं है। इसलिए, ड्राइवर जो समर्थन जोड़ते हैं वे कृत्रिम रूप से परिणामी वस्तुओं को पॉप्युलेट कर रहे हैं।
  2. अधिक, "नंगे धातु" एपीआई, जितना कम समझ में आता है। वास्तव में, के रूप में। मोंगो डीबी संग्रह स्कीमा-कम हैं, यदि नोडजेएस चालक ने सभी संदर्भों के साथ प्राथमिक दस्तावेज वापस लाया, तो कोड ने संदर्भों को तोड़ने के बिना दस्तावेज़ को सहेजा, तो इसके परिणामस्वरूप एक एम्बेडेड उप-दस्तावेज़ होगा। बेशक, यह एक गड़बड़ होगी।

जब तक आपकी फ़ील्ड मान भिन्न है, मैं एक DBRef प्रकार के साथ परेशान नहीं हैं और इसके बजाय सिर्फ ObjectId सीधे संग्रहीत करेंगे।जैसा कि आप देख सकते हैं, DBRef वास्तव में प्रत्येक संदर्भ के लिए बहुत अधिक डुप्लिकेट डिस्क स्थान की आवश्यकता के अलावा कोई लाभ नहीं प्रदान करता है, क्योंकि एक समृद्ध वस्तु को अपनी प्रकार की जानकारी के साथ संग्रहीत किया जाना चाहिए। किसी भी तरह से, आपको संदर्भित संग्रह के दस्तावेजों वाली एक स्ट्रिंग को संग्रहित करने के संभावित अनावश्यक ओवरहेड पर विचार करना चाहिए।

कई डेवलपर्स और मोंगो डीबी, इंक ने मौजूदा बेस ड्राइवरों के शीर्ष पर एक ऑब्जेक्ट दस्तावेज़ मैपिंग परत जोड़ा है। MongoDb और Nodejs के लिए एक लोकप्रिय विकल्प Mongoose है। चूंकि MongoDb सर्वर को संदर्भित दस्तावेज़ों की कोई वास्तविक जागरूकता नहीं है, संदर्भों की ज़िम्मेदारी ग्राहक को ले जाती है। चूंकि किसी दिए गए दस्तावेज़ से किसी विशेष संग्रह को लगातार संदर्भित करना अधिक आम है, इसलिए मोंगोस स्कीमा के रूप में संदर्भ को परिभाषित करना संभव बनाता है। मोंगोस स्कीमा-कम नहीं है।

यदि आप स्वीकार करते हैं और स्कीमा का उपयोग करना उपयोगी है, तो मोंगोस निश्चित रूप से देखने लायक है। यह दस्तावेजों के एक सेट से संबंधित दस्तावेजों (एक संग्रह से) के एक बैच को कुशलता से प्राप्त कर सकता है। यह हमेशा देशी चालक का उपयोग कर रहा है, लेकिन यह आम तौर पर संचालन को बेहद कुशलतापूर्वक करता है और अधिक जटिल अनुप्रयोग आर्किटेक्चर से बाहर की कुछ कठिनाइयों को लेता है।

मैं दृढ़ता से सुझाव देता हूं कि आप populate विधि (here) पर यह देखने के लिए देखें कि यह करने में सक्षम क्या है।

Demo  /* Demo would be a Mongoose Model that you've defined */ 
.findById(theObjectId) 
.populate('detail') 
.exec(function (err, doc) { 
    if (err) return handleError(err); 
    // do something with the single doc that was returned 
}) 

, तो इसके बजाय findById है, जो हमेशा एक एकल दस्तावेज़ रिटर्न की, findpopulate साथ प्रयोग किया गया, सभी लौट आए दस्तावेजों 'details संपत्ति स्वतः भर जाती है। यह भी स्मार्ट है कि यह एक ही संदर्भित दस्तावेजों का कई बार अनुरोध करेगा।

यदि आप मोंगोस का उपयोग नहीं करते हैं, तो मैं सुझाव दूंगा कि जब आप संभव हो तो क्लाइंट साइड संदर्भ में शामिल होने से बचने के लिए एक कैशिंग परत पर विचार करें और जितना संभव हो सके बैच करने के लिए $in क्वेरी ऑपरेटर का उपयोग करें।

+0

धन्यवाद, मैं मोंगोज़ पर एक नज़र डालेगा। –

1

मैं अगले उदाहरण के साथ वांछित परिणाम तक पहुँचने:

collection.find({}, function (err, cursor) { 
    cursor.toArray(function (err, docs) { 
     var count = docs.length - 1; 
     for (i in docs) { 
      (function (docs, i) { 
       db.dereference(docs[i].ref, function(err, doc) { 
        docs[i].ref = doc; 
        if (i == count) { 
         (function (docs) { 
          console.log(docs); 
         })(docs); 
        } 
       }); 
      })(docs, i) 
     } 
    }); 
}); 

सुनिश्चित नहीं हैं कि यह समाधान सर्वश्रेष्ठ में से सबसे अच्छा है, लेकिन यह आसान समाधान है कि मैंने पाया है।