आपके वर्तमान स्कीमा में marks
हैं फ़ील्ड डेटा प्रकार स्ट्रिंग के रूप में और योग को निकालने के लिए आपको अपने एकत्रीकरण ढांचे के लिए एक पूर्णांक डेटा प्रकार की आवश्यकता होती है। दूसरी ओर, आप MapReduce
का उपयोग कर सकते हैं। योग की गणना करने के लिए क्योंकि यह मूल जावास्क्रिप्ट विधियों जैसे parseInt()
. के उपयोग की अनुमति देता है इसके मानचित्र कार्यों में आपके ऑब्जेक्ट गुणों पर। तो कुल मिलाकर आपके पास दो विकल्प हैं।
विकल्प 1:स्कीमा अपडेट करें (डेटा प्रकार बदलें)
पहला यह होगा कि आप स्कीमा को बदलें या अपने दस्तावेज़ में कोई अन्य फ़ील्ड जोड़ें जिसमें वास्तविक संख्यात्मक मान हो, न कि स्ट्रिंग प्रतिनिधित्व। यदि आपके संग्रह दस्तावेज़ का आकार अपेक्षाकृत छोटा है, तो आप मोंगोडब के कर्सर के संयोजन का उपयोग कर सकते हैं find()
, forEach()
और update()
अपने मार्क्स स्कीमा को बदलने के तरीके:
db.student.find({ "marks": { "$type": 2 } }).snapshot().forEach(function(doc) {
db.student.update(
{ "_id": doc._id, "marks": { "$type": 2 } },
{ "$set": { "marks": parseInt(doc.marks) } }
);
});
अपेक्षाकृत बड़े संग्रह आकारों के लिए, आपका डीबी प्रदर्शन धीमा होगा और इसका उपयोग करने की अनुशंसा की जाती है मोंगो बल्क अपडेट इसके लिए:
MongoDB संस्करण>=2.6 और <3.2:
var bulk = db.student.initializeUnorderedBulkOp(),
counter = 0;
db.student.find({"marks": {"$exists": true, "$type": 2 }}).forEach(function (doc) {
bulk.find({ "_id": doc._id }).updateOne({
"$set": { "marks": parseInt(doc.marks) }
});
counter++;
if (counter % 1000 === 0) {
// Execute per 1000 operations
bulk.execute();
// re-initialize every 1000 update statements
bulk = db.student.initializeUnorderedBulkOp();
}
})
// Clean up remaining operations in queue
if (counter % 1000 !== 0) bulk.execute();
MongoDB संस्करण 3.2 और नया:
var ops = [],
cursor = db.student.find({"marks": {"$exists": true, "$type": 2 }});
cursor.forEach(function (doc) {
ops.push({
"updateOne": {
"filter": { "_id": doc._id } ,
"update": { "$set": { "marks": parseInt(doc.marks) } }
}
});
if (ops.length === 1000) {
db.student.bulkWrite(ops);
ops = [];
}
});
if (ops.length > 0) db.student.bulkWrite(ops);
विकल्प 2:MapReduce चलाएँ
दूसरा तरीका यह होगा कि आप अपनी क्वेरी को MapReduce
के साथ फिर से लिखें। जहां आप जावास्क्रिप्ट फ़ंक्शन का उपयोग कर सकते हैं parseInt()
.
आपके MapReduce
में ऑपरेशन, प्रत्येक इनपुट दस्तावेज़ को संसाधित करने वाले मानचित्र फ़ंक्शन को परिभाषित करें। यह फ़ंक्शन रूपांतरित marks
. को मैप करता है subject
. के लिए स्ट्रिंग मान प्रत्येक दस्तावेज़ के लिए, और subject
. उत्सर्जित करता है और रूपांतरित marks
जोड़ा। यह वह जगह है जहां जावास्क्रिप्ट मूल कार्य करता है parseInt()
लागु कर सकते हे। नोट:फंक्शन में, this
दस्तावेज़ को संदर्भित करता है कि नक्शा-कम करने का कार्य संसाधित हो रहा है:
var mapper = function () {
var x = parseInt(this.marks);
emit(this.subject, x);
};
इसके बाद, संबंधित कम करें फ़ंक्शन को दो तर्कों के साथ परिभाषित करें keySubject
और valuesMarks
. valuesMarks
एक सरणी है जिसके तत्व पूर्णांक हैं marks
मैप फ़ंक्शन द्वारा उत्सर्जित और keySubject
. द्वारा समूहीकृत मान .फ़ंक्शन valuesMarks
. को कम करता है इसके तत्वों के योग के लिए सरणी।
var reducer = function(keySubject, valuesMarks) {
return Array.sum(valuesMarks);
};
db.student.mapReduce(
mapper,
reducer,
{
out : "example_results",
query: { subject : "maths" }
}
);
आपके संग्रह के साथ, उपरोक्त आपके MapReduce एकत्रीकरण परिणाम को एक नए संग्रह db.example_results
में डाल देगा . इस प्रकार, db.example_results.find()
आउटपुट होगा:
/* 0 */
{
"_id" : "maths",
"value" : 163
}