आप इसे सही तरीके से कर रहे हैं लेकिन आपने .update()
के क्वेरी भाग में मिलान करने के लिए सरणी तत्व शामिल नहीं किया है :
db.collectionName.find({
"topProcesses":{"$exists":true}}).forEach(function(data){
for(var ii=0;ii<data.topProcesses.length;ii++) {
db.collectionName.update(
{
"_id": data._id,
"topProcesses.processId": data.topProcesses[ii].processId // corrected
},
{
"$set": {
"topProcesses.$.cpuUtilizationPercent":
parseFloat(data.topProcesses[ii].cpuUtilizationPercent)
}
}
);
}
})
तो आपको स्थितिगत <कोड के लिए सरणी में कुछ मिलान करने की आवश्यकता है>$ ऑपरेटर का कोई प्रभाव होगा।
आप नोटेशन में "इंडेक्स" मान का भी उपयोग कर सकते थे, क्योंकि आप इसे किसी भी तरह से लूप में बना रहे हैं:
db.collectionName.find({
"topProcesses":{"$exists":true}}).forEach(function(data){
for(var ii=0;ii<data.topProcesses.length;ii++) {
var updoc = {
"$set": {}
};
var myKey = "topProcesses." + ii + ".cpuUtilizationPercent";
updoc["$set"][myKey] = parseFloat(data.topProcesses[ii].cpuUtilizationPercent);
db.collectionName.update(
{
"_id": data._id
},
updoc
);
}
})
जो सिर्फ मैचिंग इंडेक्स का उपयोग करता है और आसान है जहां एरे एलिमेंट का कोई यूनिक आइडेंटिफायर नहीं है।
यह भी ध्यान दें कि मौजूदा दस्तावेज़ों को संसाधित करने की प्रकृति के कारण यहां न तो "अप्सर्ट" या "मल्टी" विकल्प लागू होने चाहिए।
इसके लिए एक "पोस्टस्क्रिप्ट" नोट के रूप में, मोंगोडीबी के थोक संचालन एपीआई को 2.6 और उससे अधिक के संस्करणों में विचार करना भी उपयुक्त है। इन एपीआई विधियों का उपयोग करके आप अपने क्लाइंट एप्लिकेशन और डेटाबेस के बीच नेटवर्क ट्रैफ़िक की मात्रा को काफी कम कर सकते हैं। यहाँ स्पष्ट सुधार समग्र गति में है:
var bulk = db.collectionName.initializeOrderedBulkOp();
var counter = 0;
db.collectionName.find({
"topProcesses":{"$exists":true}}
).forEach(function(data){
for(var ii=0;ii<data.topProcesses.length;ii++) {
var updoc = {
"$set": {}
};
var myKey = "topProcesses." + ii + ".cpuUtilizationPercent";
updoc["$set"][myKey] = parseFloat(data.topProcesses[ii].cpuUtilizationPercent);
// queue the update
bulk.find({ "_id": data._id }).update(updoc);
counter++;
// Drain and re-initialize every 1000 update statements
if ( counter % 1000 == 0 ) {
bulk.execute();
bulk = db.collectionName.initializeOrderedBulkOp();
}
}
})
// Add the rest in the queue
if ( counter % 1000 != 0 )
bulk.execute();
यह मूल रूप से सेवर को भेजे गए ऑपरेशन स्टेटमेंट की मात्रा को कम कर देता है, केवल प्रत्येक 1000 कतारबद्ध संचालन में एक बार भेजने के लिए। आप उस संख्या के साथ खेल सकते हैं और चीजों को कैसे समूहीकृत किया जाता है लेकिन यह अपेक्षाकृत सुरक्षित तरीके से गति में उल्लेखनीय वृद्धि देगा।