MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

MongoDB के साथ एक ऐरे को अपडेट करने का आसान तरीका

यदि आप यहां थोड़ी अधिक कार्यक्षमता जोड़ने के बारे में "परवाह करते हैं" (बहुत सलाह दी जाती है) और अपडेट के ऊपरी हिस्से को सीमित करना जहां आपको वास्तव में संशोधित दस्तावेज़ को वापस करने की आवश्यकता नहीं है, या यहां तक ​​​​कि यदि आप करते हैं तो परमाणु ऑपरेटरों का उपयोग करना हमेशा बेहतर होता है $push जैसी सरणियों के साथ और $addToSet

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

यहां बेहतर निर्माण "बल्क" संचालन का उपयोग करना है। चूंकि सरणी तत्वों के लिए परीक्षण "अप्सर्ट्स" की अवधारणा के साथ अच्छी तरह से मिश्रण नहीं करता है, इसलिए जहां आप अप्सर्ट कार्यक्षमता चाहते हैं, एक सरणी परीक्षण दो परिचालनों में बेहतर है। लेकिन चूंकि "एक अनुरोध" के साथ "थोक" संचालन सर्वर पर भेजा जा सकता है और आपको "एक प्रतिक्रिया" भी मिलती है, तो यह ऐसा करने में किसी भी वास्तविक ओवरहेड को कम करता है।

var bulk = FollowModel.collection.initializeOrderedBulkOp();

// Try to add where not found in array
bulk.find({ 
    "facebookId": req.user.facebookId,
    "players": { "$ne": req.body.idToFollow }
}).updateOne({
    "$push": { "players": req.body.idToFollow },
    "$inc": { "playerCount": 1 }
});

// Otherwise create the document if not matched
bulk.find({
    "facebookId": req.user.facebookId,
}).upsert().updateOne({
    "$setOnInsert": {
        "players": [req.body.idToFollow]
        "playerCount": 1,
        "fans": [],
        "fanCount": 0
    }
})

bulk.execute(function(err,result) {
    // Handling in here
});

जिस तरह से यह काम करता है वह यह है कि पहला प्रयास उस दस्तावेज़ को खोजने का प्रयास करता है जहां सरणी तत्व जोड़ा जाना पहले से ही सरणी के भीतर मौजूद नहीं है। यहां "अप्सर्ट" पर कोई प्रयास नहीं किया गया है क्योंकि आप एक नया दस्तावेज़ नहीं बनाना चाहते हैं यदि एकमात्र कारण यह दस्तावेज़ से मेल नहीं खाता है क्योंकि सरणी तत्व मौजूद नहीं है। लेकिन जहां मिलान किया जाता है, फिर नए सदस्य को सरणी में जोड़ा जाता है और वर्तमान "गिनती" को $inc , जो कुल गिनती या लंबाई रखता है।

इसलिए दूसरा कथन केवल दस्तावेज़ से मेल खाने वाला है, और इसलिए "अप्सर्ट" का उपयोग करता है क्योंकि यदि कुंजी फ़ील्ड के लिए दस्तावेज़ नहीं मिला है तो इसे बनाया जाएगा। चूंकि सभी संचालन $setOnInsert यदि दस्तावेज़ पहले से मौजूद है तो कोई कार्रवाई नहीं की जाएगी।

यह वास्तव में केवल एक सर्वर अनुरोध और प्रतिक्रिया है, इसलिए दो अद्यतन संचालनों को शामिल करने के लिए कोई "आगे और पीछे" नहीं है, और यह इसे कुशल बनाता है।

एक सरणी प्रविष्टि को हटाना मूल रूप से उल्टा है, सिवाय इसके कि इस बार एक नया दस्तावेज़ "बनाने" की कोई आवश्यकता नहीं है अगर यह नहीं मिला:

var bulk = FollowModel.collection.initializeOrderedBulkOp();

// Try to remove where found in array
bulk.find({ 
    "facebookId": req.user.facebookId,
    "players": req.body.idToFollow
}).updateOne({
     "$pull": { "players": req.body.idToFollow },
     "$inc": { "playerCount": -1 }
});

bulk.execute(function(err,result) {
    // Handling in here
});

तो अब आपको केवल यह जांचने की आवश्यकता है कि सरणी तत्व कहां मौजूद है और यह कहां है $खींचें सरणी सामग्री से मेल खाने वाला तत्व, साथ ही निष्कासन को दर्शाने के लिए "गिनती" को 1 से "घटाना" के रूप में।

अब आप $addToSet . का उपयोग "कर सकते हैं" इसके बजाय यहां क्योंकि यह केवल सरणी सामग्री को देखेगा और यदि सदस्य नहीं मिला है तो इसे जोड़ा जाएगा, और उन्हीं कारणों से $pull का उपयोग करते समय मौजूद सरणी तत्व के परीक्षण की कोई आवश्यकता नहीं है। कोड> क्योंकि अगर तत्व नहीं है तो यह कुछ भी नहीं करेगा। इसके अलावा $addToSet उस संदर्भ में सीधे "अप्सर्ट" के भीतर उपयोग किया जा सकता है, जब तक कि आप "क्रॉस पथ" नहीं करते हैं क्योंकि इसे मोंगोडीबी के साथ एक ही पथ पर एकाधिक अपडेट ऑपरेटरों को आजमाने और उपयोग करने की अनुमति नहीं है:

FollowModel.update(
    { "facebookId": req.user.facebookId },
    {
        "$setOnInsert": {
            "fans": []
        },
        "$addToSet": { "players": req.body.idToFollow }
    },
    { "upsert": true },
    function(err,numAffected) {
        // handling in here
    }
);

लेकिन यह "गलत" होगा:

FollowModel.update(
    { "facebookId": req.user.facebookId },
    {
        "$setOnInsert": {
            "players": [],              // <-- This is a conflict
            "fans": []
        },
        "$addToSet": { "players": req.body.idToFollow }
    },
    { "upsert": true },
    function(err,numAffected) {
        // handling in here
    }
);

हालांकि, ऐसा करने से आप "गिनती" कार्यक्षमता खो देते हैं क्योंकि इस तरह के संचालन वास्तव में क्या है या कुछ भी "जोड़ा" या "हटा दिया गया" के संबंध में पूरा कर रहे हैं।

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

यहां त्वरित सिडेनोट जैसा कि मैं आमतौर पर जहां संभव हो वहां "थोक" संचालन की सलाह देता हूं। .संग्रह . के माध्यम से इसका उपयोग करते समय नेवला में एक्सेसर, तो आपको इस बात की जानकारी होनी चाहिए कि ये मूल ड्राइवर विधियाँ हैं और इसलिए "मोंगोज़" विधियों की तुलना में अलग व्यवहार करते हैं।

विशेष रूप से, सभी "मोंगोज़" विधियों में यह देखने के लिए एक "चेक" है कि डेटाबेस से कनेक्शन वर्तमान में सक्रिय है। जहां यह नहीं है, कनेक्शन होने तक ऑपरेशन प्रभावी रूप से "कतार" होता है। देशी तरीकों का उपयोग करके यह "चेक" अब मौजूद नहीं है। इसलिए आपको या तो यह सुनिश्चित करने की आवश्यकता है कि "नेवला" विधि से एक कनेक्शन पहले से मौजूद है, "पहले" निष्पादित किया गया है, या वैकल्पिक रूप से आपको पूरे एप्लिकेशन तर्क को एक ऐसे निर्माण में लपेटता है जो कनेक्शन के लिए "इंतजार" करता है:

mongoose.connection.on("open",function(err) {
    // All app logic or start in here
});

इस तरह आप सुनिश्चित हैं कि एक कनेक्शन मौजूद है और सही वस्तुओं को वापस किया जा सकता है और विधियों द्वारा उपयोग किया जा सकता है। लेकिन कोई कनेक्शन नहीं, और "बल्क" संचालन विफल हो जाएगा।



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. मैं ट्विटर के स्ट्रीमिंग एपीआई से ट्वीट्स का उपभोग कैसे कर सकता हूं और उन्हें मोंगोडब में स्टोर कर सकता हूं

  2. मैं रेल 3 में समानांतर में Mongoid और ActiveRecord का उपयोग कैसे कर सकता हूं?

  3. दो अलग-अलग संग्रहों में डुप्लिकेट मोंगो ऑब्जेक्ट आईडी उत्पन्न होने की संभावना?

  4. दो बिंदुओं के बीच MongoDB प्रिंट दूरी

  5. मोंगोडब कुल कई सरणियाँ