2015-09-07 16 views
8

छोड़ें क्या मोंगो में स्थिति के साथ डालना संभव है;MongoDB- अगर यह मौजूद नहीं है, तो डालें, अन्यथा

//Pseudo code 

Bulk Insert Item : 

If Key exists 
    Skip, don't throw error 
If key does not exist 
    Add item 

तो मैं अकेला आवेषण करते हैं, यह एक त्रुटि वापस कर सकती है या संग्रह में सम्मिलित है, लेकिन यह थोक में संभव है?

+0

पढ़ें [ "Upsert"] (http: //docs.mongodb। org/मैनुअल/संदर्भ/विधि/db.collection.update/# Upsert-विकल्प)। चूंकि मोंगोडीबी ऐसा करता है। थोक संचालन के लिए आवश्यक संशोधक के रूप में '.upsert()' है। इसके अलावा ['$ setOnInsert'] (http://docs.mongodb.org/manual/reference/operator/update/setOnInsert/) केवल एक नया दस्तावेज़" डाला गया "परिवर्तन लागू करेगा और अन्यथा कुछ भी नहीं होने पर कुछ भी नहीं होगा वह ब्लॉक –

उत्तर

12

आप दो असली विकल्प यहाँ आप कैसे चीजें हैंडल करना चाहते हैं पर निर्भर करता है:

  1. उपयोग upsert MongoDB की कार्यक्षमता अनिवार्य रूप से "देखने" कुंजी डेटा मौजूद है। यदि नहीं तो आप केवल $setOnInsert पर डेटा पास करते हैं और यह किसी और चीज़ को छूएगा नहीं।

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

पूरे उदाहरण:

var async = require('async'), 
    mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

var testSchema = new Schema({ 
    "_id": Number, 
    "name": String 
},{ "_id": false }); 

var Test = mongoose.model('Test',testSchema,'test'); 

mongoose.connect('mongodb://localhost/test'); 

var data = [ 
    { "_id": 1, "name": "One" }, 
    { "_id": 1, "name": "Another" }, 
    { "_id": 2, "name": "Two" } 
]; 

async.series(
    [ 
    // Start fresh 
    function(callback) { 
     Test.remove({},callback); 
    }, 

    // Ordered will fail on error. Upserts never fail! 
    function(callback) { 
     var bulk = Test.collection.initializeOrderedBulkOp(); 
     data.forEach(function(item) { 
     bulk.find({ "_id": item._id }).upsert().updateOne({ 
      "$setOnInsert": { "name": item.name } 
     }); 
     }); 
     bulk.execute(callback); 
    }, 

    // All as expected 
    function(callback) { 
     Test.find().exec(function(err,docs) { 
     console.log(docs) 
     callback(err); 
     }); 
    }, 


    // Start again 
    function(callback) { 
     Test.remove({},callback); 
    }, 

    // Unordered will just continue on error and record an error 
    function(callback) { 
     var bulk = Test.collection.initializeUnorderedBulkOp(); 
     data.forEach(function(item) { 
     bulk.insert(item); 
     }); 
     bulk.execute(function(err,result) { 
     callback(); // so what! Could not care about errors 
     }); 
    }, 


    // Still processed the whole batch 
    function(callback) { 
     Test.find().exec(function(err,docs) { 
     console.log(docs) 
     callback(err); 
     }); 
    } 
    ], 
    function(err) { 
    if (err) throw err; 
    mongoose.disconnect(); 
    } 
); 

ध्यान दें कि "बदली हुई कार्रवाई" वर्तमान चालकों में है कि .execute()पर परिणाम प्रतिक्रिया एक त्रुटि वस्तु वापस आ जाएगी, फेंक दिया है, जहां पूर्व में जारी हुए ऐसा नहीं किया है "अन-आदेशित" संचालन के साथ ऐसा करें।

यह आवश्यक है कि आपका कोड कभी भी err पर निर्भर न हो, और आपको त्रुटियों के पूर्ण वर्गीकरण के लिए result लौटाया जाना चाहिए।

फिर भी, जब unordered तो बैच अंत तक जारी रहता है, इससे कोई फर्क नहीं पड़ता कि कितनी त्रुटियां होती हैं। चीजें जो त्रुटि नहीं हैं सामान्य के रूप में प्रतिबद्ध की जाएगी।

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

साथ ही, "थोक" संचालन को सक्षम करने के लिए आधार चालक से अंतर्निहित संग्रहण ऑब्जेक्ट प्राप्त करने के लिए .collection का उपयोग करते समय, हमेशा सुनिश्चित करें कि या तो "कुछ" मोंगोस विधि को हमेशा पहले कहा जाता है।

इसके बिना, मूल ड्राइवर विधियों के साथ डेटाबेस के लिए कोई गारंटीकृत कनेक्शन नहीं है क्योंकि इसे मोंगोस विधियों के लिए संभाला जाता है, इसलिए ऑपरेशन किसी कनेक्शन के कारण विफल हो जाएगा।

वैकल्पिक "फायरिंग" करने के लिए एक नेवला विधि पहले, कनेक्शन के लिए एक घटना श्रोता में अपने ऐप्लिकेशन के तर्क रैप करने के लिए है:

mongoose.connection.on("open",function(err) { 
    // app logic in here 
}) 
+1

बहुत बढ़िया! धन्यवाद –

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