यहां समस्या यह है कि आप जो लूप चला रहे हैं वह प्रत्येक ऑपरेशन के पूरा होने की प्रतीक्षा नहीं कर रहा है। तो वास्तव में आप केवल 1000 .save()
. की कतार में हैं अनुरोध और उन्हें एक साथ चलाने की कोशिश कर रहा है। आप उचित सीमाओं के भीतर ऐसा नहीं कर सकते, इसलिए आपको त्रुटि प्रतिक्रिया मिलती है।
async मॉड्यूल में उस पुनरावर्तक के लिए कॉलबैक संसाधित करते समय पुनरावृति के लिए विभिन्न तरीके हैं, जहां संभवतः सबसे सरल प्रत्यक्ष है जबकि . Mongoose कॉलबैक के भीतर एम्बेड किए बिना आपके लिए कनेक्शन प्रबंधन को भी संभालता है, क्योंकि मॉडल कनेक्शन के बारे में जानते हैं:
var tempColSchema = new Schema({
cid: {
type: Number,
required: true
},
loc:[]
});
var TempCol = mongoose.model( "TempCol", tempColSchema );
mongoose.connect( 'mongodb://localhost/mean-dev' );
var i = 0;
async.whilst(
function() { return i < 10000000; },
function(callback) {
i++;
var c = i;
console.log(c);
var lon = parseInt(c/100000);
var lat = c%100000;
new Tempcol({cid: Math.random(), loc: [lon, lat]}).save(function(err){
callback(err);
});
},
function(err) {
// When the loop is complete or on error
}
);
ऐसा करने का सबसे शानदार तरीका नहीं है, यह अभी भी एक समय में एक लेखन है और आप समवर्ती संचालन को "शासन" करने के लिए अन्य विधियों का उपयोग कर सकते हैं, लेकिन यह कम से कम कॉल स्टैक को उड़ा नहीं देगा।
प्रपत्र MongoDB 2.6 और इससे अधिक आप बल्क ऑपरेशंस API का उपयोग कर सकते हैं सर्वर पर एक समय में एक से अधिक लेखन को संसाधित करने के लिए। तो प्रक्रिया समान है, लेकिन इस बार आप सर्वर को एक बार में एक बार में 1000 भेज सकते हैं, जो बहुत तेज है:
var tempColSchema = new Schema({
cid: {
type: Number,
required: true
},
loc:[]
});
var TempCol = mongoose.model( "TempCol", tempColSchema );
mongoose.connect( 'mongodb://localhost/mean-dev' );
mongoose.on("open",function(err,conn) {
var i = 0;
var bulk = TempCol.collection.initializeOrderedBulkOp();
async.whilst(
function() { return i < 10000000; },
function(callback) {
i++;
var c = i;
console.log(c);
var lon = parseInt(c/100000);
var lat = c%100000;
bulk.insert({ "cid": Math.random(), "loc": [ lon, lat ] });
if ( i % 1000 == 0 ) {
bulk.execute(function(err,result) {
bulk = TempCol.collection.initializeOrderedBulkOp();
callback(err);
});
} else {
process.nextTick(callback);
}
},
function(err) {
// When the loop is complete or on error
// If you had a number not plainly divisible by 1000
if ( i % 1000 != 0 )
bulk.execute(function(err,result) {
// possibly check for errors here
});
}
);
});
यह वास्तव में मूल ड्राइवर विधियों का उपयोग कर रहा है जो अभी तक नेवले में उजागर नहीं हुए हैं, इसलिए यह सुनिश्चित करने के लिए अतिरिक्त देखभाल की जा रही है कि कनेक्शन उपलब्ध है। यह एक उदाहरण है लेकिन एकमात्र तरीका नहीं है, लेकिन मुख्य बिंदु यह है कि नेवला "जादू" यहां कनेक्शन के लिए नहीं बनाया गया है, इसलिए आपको सुनिश्चित होना चाहिए कि यह स्थापित है।
आपके पास संसाधित करने के लिए कई आइटम हैं, लेकिन जहां ऐसा नहीं है, आपको bulk.execute()
पर कॉल करना चाहिए। उस अंतिम ब्लॉक में और साथ ही दिखाया गया है, लेकिन यह मोडुलो को प्रतिक्रिया देने वाली संख्या पर निर्भर करता है।
मुख्य बिंदु संचालन के ढेर को अनुचित आकार में नहीं बढ़ाना है, और प्रसंस्करण को सीमित रखना है। यहां प्रवाह नियंत्रण उन कार्यों की अनुमति देता है जिन्हें अगले पुनरावृत्ति पर जाने से पहले वास्तव में पूरा होने में कुछ समय लगेगा। तो या तो बैच अपडेट या कुछ अतिरिक्त समानांतर कतार वही है जो आप सर्वश्रेष्ठ प्रदर्शन के लिए चाहते हैं।
.initializeUnorderedBulkOp()
. भी है इसके लिए फॉर्म करें यदि आप नहीं चाहते कि लिखने की त्रुटियां घातक हों, लेकिन इसके बजाय उन्हें एक अलग तरीके से संभालें। ज्यादातर बल्क एपीआई पर आधिकारिक दस्तावेज और दिए गए जवाब की व्याख्या करने के तरीके के लिए प्रतिक्रियाएं देखें।