2011-11-21 15 views
6

सी # प्रलेखन से:MongoDB सी # collection.Save बनाम सम्मिलित + अद्यतन

सहेजें विधि सम्मिलित और अद्यतन का एक संयोजन है। यदि दस्तावेज़ के आईडी सदस्य के पास कोई मान है, तो यह दस्तावेज़ पर एक मौजूदा दस्तावेज़ और सहेजें कॉल अपडेट माना जाता है (उपरोक्त ध्वज सेट करना केवल तभी होता है जब यह वास्तव में एक नया दस्तावेज़ है)।

मैं अपने आईडी को मैन्युअल रूप से बेस क्लास में बना रहा हूं जो मेरे सभी डोमेन ऑब्जेक्ट्स से प्राप्त होता है। इसलिए जब मेरे पास मोंगोडीबी में डाला जाता है तो मेरे सभी डोमेन ऑब्जेक्ट्स में एक आईडी होती है।

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

जो मैं सोच रहा हूं वह है कि सहेजें विधि पहले कॉलिंग अपडेट कर रही है और फिर यह पता लगाती है कि मेरी नई वस्तु पहले स्थान पर मौजूद नहीं थी, और फिर इसके बजाय सम्मिलित करें। क्या मै गलत हु? क्या किसी ने इसका परीक्षण किया है?

नोट: मैं सम्मिलित बैच के साथ थोक डेटा डालता हूं, इसलिए इस मामले में बड़ी डेटाचंक्स कोई फर्क नहीं पड़ता।

संपादित करें, अनुवर्ती

मैं एक छोटे से परीक्षण लिखा था पता लगाने के लिए अगर Upsert ध्वज के साथ बुला अद्यतन कुछ भूमि के ऊपर था तो सम्मिलित बेहतर हो सकता है। बाहर निकला कि वे एक ही गति से दौड़ते हैं। नीचे मेरा टेस्ट कोड देखें। मोंगो डीबी सर्वर और IMongoDbServer भंडारण सुविधा को अलग करने के लिए मेरा खुद का सामान्य इंटरफ़ेस है।

IMongoDbServer server = new MongoDbServer(); 
Stopwatch sw = new Stopwatch(); 
long d1 = 0; 
long d2 = 0; 
for (int w = 0; w <= 100; w++) 
{ 
    sw.Restart(); 
    for (int i = 0; i <= 10000; i++) 
    { 
     ProductionArea area = new ProductionArea(); 
     server.Save(area); 
    } 
    sw.Stop(); 
    d1 += sw.ElapsedMilliseconds; 
    sw.Restart(); 
    for (int i = 0; i <= 10000; i++) 
    { 
     ProductionArea area = new ProductionArea(); 
     server.Insert(area); 
    } 
    sw.Stop(); 
    d2 += sw.ElapsedMilliseconds; 
} 
long a1 = d1/100; 
long a2 = d2/100; 

उत्तर

12

सहेजें विधि नहीं सर्वर से दो यात्राएं बनाने जा रहा है।

हेरिस्टिक यह है: यदि दस्तावेज़ सहेजा जा रहा है तो _id फ़ील्ड के लिए कोई मान नहीं है, उसके बाद एक मान उत्पन्न होता है और फिर सम्मिलित किया जाता है। यदि सहेजे जा रहे दस्तावेज़ में _id के लिए गैर-शून्य मान है, तो अद्यतन अप्सर्ट ध्वज के साथ कहा जाता है, इस स्थिति में यह तय करने के लिए सर्वर पर निर्भर करता है कि कोई सम्मिलन या अद्यतन करना है या नहीं।

मुझे नहीं पता कि एक अप्सर्ट एक सम्मिलन से अधिक महंगा है या नहीं। मुझे संदेह है कि वे लगभग समान हैं और वास्तव में क्या मायने रखता है कि किसी भी तरह से यह एक नेटवर्क दौर यात्रा है।

यदि आपको पता है कि यह एक नया दस्तावेज़ है तो आप सम्मिलित करने के साथ-साथ कॉल भी कर सकते हैं। और InsertBatch को कॉल करना तरीका कई व्यक्तिगत सम्मिलन कॉल करने से अधिक प्रदर्शन करने वाला है। तो निश्चित रूप से बचाने के लिए InsertBatch पसंद करते हैं।

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