MongoDB
थोक संचालन
खोज…
टिप्पणियों
एक एकल संग्रह के लिए थोक में प्रदर्शन करने के लिए लिखने के कार्यों की एक सूची का निर्माण।
एक फ़ील्ड को दूसरे प्रकार में परिवर्तित करना और बल्क में पूरे संग्रह को अपडेट करना
आमतौर पर जब कोई एक फ़ील्ड प्रकार को दूसरे में बदलना चाहता है, उदाहरण के लिए मूल संग्रह में "संख्यात्मक" या "दिनांक" फ़ील्ड स्ट्रिंग के रूप में सहेजे जा सकते हैं:
{
"name": "Alice",
"salary": "57871",
"dob": "1986-08-21"
},
{
"name": "Bob",
"salary": "48974",
"dob": "1990-11-04"
}
इसका उद्देश्य उपरोक्त की तरह एक विनम्र संग्रह को अद्यतन करना होगा
{
"name": "Alice",
"salary": 57871,
"dob": ISODate("1986-08-21T00:00:00.000Z")
},
{
"name": "Bob",
"salary": 48974,
"dob": ISODate("1990-11-04T00:00:00.000Z")
}
अपेक्षाकृत छोटे डेटा के लिए, कोई भी कर्सर की forEach()
पद्धति के साथ snapshot
का उपयोग करके संग्रह को पुनरावृत्त करके इसे प्राप्त कर सकता है और प्रत्येक दस्तावेज़ को निम्नानुसार अपडेट कर सकता है:
db.test.find({
"salary": { "$exists": true, "$type": 2 },
"dob": { "$exists": true, "$type": 2 }
}).snapshot().forEach(function(doc){
var newSalary = parseInt(doc.salary),
newDob = new ISODate(doc.dob);
db.test.updateOne(
{ "_id": doc._id },
{ "$set": { "salary": newSalary, "dob": newDob } }
);
});
जबकि यह छोटे संग्रह के लिए इष्टतम है, एक बड़े डेटासेट के माध्यम से लूपिंग के बाद से बड़े संग्रह के साथ प्रदर्शन बहुत कम हो जाता है और सर्वर के प्रति प्रत्येक अद्यतन संचालन को एक कम्प्यूटेशनल जुर्माना लगाता है।
Bulk()
एपीआई बचाव के लिए आता है और प्रदर्शन में सुधार करता है क्योंकि लिखने का संचालन केवल एक बार थोक में सर्वर को भेजा जाता है। दक्षता प्राप्त की जाती है क्योंकि विधि सर्वर को हर लिखने का अनुरोध नहीं भेजती है (जैसा कि forEach()
लूप के भीतर वर्तमान अपडेट स्टेटमेंट के साथ) लेकिन हर 1000 अनुरोधों में सिर्फ एक बार, इस प्रकार अपडेट वर्तमान में की तुलना में अधिक कुशल और तेज होता है।
बैच बनाने के लिए forEach()
लूप के साथ ऊपर एक ही अवधारणा का उपयोग करके, हम निम्नानुसार संग्रह को थोक में अपडेट कर सकते हैं। इस प्रदर्शन में Bulk()
API MongoDB संस्करणों में उपलब्ध >= 2.6
और < 3.2
समानांतर में निष्पादित करने के लिए initializeUnorderedBulkOp()
विधि का उपयोग करता है, साथ ही साथ एक nondeterministic क्रम में, बैचों में लिखने का संचालन करता है।
यह ग्राहकों के संग्रह में सभी दस्तावेजों को क्रमशः numerical
और datetime
मानों में salary
और dob
फ़ील्ड बदलकर अद्यतन करता है:
var bulk = db.test.initializeUnorderedBulkOp(),
counter = 0; // counter to keep track of the batch update size
db.test.find({
"salary": { "$exists": true, "$type": 2 },
"dob": { "$exists": true, "$type": 2 }
}).snapshot().forEach(function(doc){
var newSalary = parseInt(doc.salary),
newDob = new ISODate(doc.dob);
bulk.find({ "_id": doc._id }).updateOne({
"$set": { "salary": newSalary, "dob": newDob }
});
counter++; // increment counter
if (counter % 1000 == 0) {
bulk.execute(); // Execute per 1000 operations and re-initialize every 1000 update statements
bulk = db.test.initializeUnorderedBulkOp();
}
});
अगला उदाहरण नए MongoDB संस्करण 3.2
पर लागू होता है जो तब से Bulk()
एपीआई को हटा दिया गया है और bulkWrite()
का उपयोग करके bulkWrite()
का एक नया सेट प्रदान करता है।
यह ऊपर के समान कर्सर का उपयोग करता है, लेकिन एक ही forEach()
कर्सर विधि का उपयोग करके बल्क ऑपरेशंस के साथ सरणियों को बनाता है ताकि प्रत्येक बल्क forEach()
पर पुश किया जा सके। चूँकि लिखने के आदेश 1000 से अधिक परिचालनों को स्वीकार नहीं कर सकते हैं, इसलिए समूह के संचालन की आवश्यकता है कि अधिकांश 1000 ऑपरेशन हों और लूप के 1000 पुनरावृत्ति होने पर सरणी को फिर से परिभाषित करें:
var cursor = db.test.find({
"salary": { "$exists": true, "$type": 2 },
"dob": { "$exists": true, "$type": 2 }
}),
bulkUpdateOps = [];
cursor.snapshot().forEach(function(doc){
var newSalary = parseInt(doc.salary),
newDob = new ISODate(doc.dob);
bulkUpdateOps.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "salary": newSalary, "dob": newDob } }
}
});
if (bulkUpdateOps.length === 1000) {
db.test.bulkWrite(bulkUpdateOps);
bulkUpdateOps = [];
}
});
if (bulkUpdateOps.length > 0) { db.test.bulkWrite(bulkUpdateOps); }