अपनी आवेदन आवश्यकताओं के आधार पर, आप स्कोर की गणना के लिए एकत्रीकरण ढांचे का उपयोग कर सकते हैं और bulkWrite()
अपने संग्रह को अद्यतन करने के लिए। निम्नलिखित उदाहरण पर विचार करें जो <कोड का उपयोग करता है>$प्रोजेक्ट
अंकगणितीय ऑपरेटरों के साथ स्कोर गणना के लिए पाइपलाइन कदम।
चूंकि C3
. की गणना के लिए तर्क आपके प्रश्न में 1
. से एक नंबर मिल रहा है करने के लिए 7
जो बिल्कुल बराबर है 7 - अंकों की संख्या (.)
, एकमात्र व्यवहार्य दृष्टिकोण जिसके बारे में मैं सोच सकता हूं, एक अतिरिक्त फ़ील्ड को संग्रहीत करना है जो एकत्रीकरण करने से पहले इस मान को रखता है। तो आपका पहला कदम उस अतिरिक्त फ़ील्ड को बनाना होगा और आप इसके बारे में bulkWrite()
इस प्रकार:
चरण 1:अतिरिक्त daysInWeek
. को समायोजित करने के लिए स्कीमा संशोधित करें फ़ील्ड
var counter = 0, bulkUpdateOps = [];
db.collection1.find({
"Field5": { "$exists": true }
}).forEach(function(doc) {
// calculations for getting the number of points in Field5
var points, daysInWeek;
points = (doc.Field5.match(new RegExp(".", "g")) || []).length;
daysInWeek = 7 - points;
bulkUpdateOps.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": {
"$set": { "daysInWeek": daysInWeek }
}
}
});
counter++;
if (counter % 500 == 0) {
db.collection1.bulkWrite(bulkUpdateOps);
bulkUpdateOps = [];
}
});
if (counter % 500 != 0) { db.collection1.bulkWrite(bulkUpdateOps); }
आदर्श रूप से उपरोक्त ऑपरेशन आपके प्रश्न में अन्य स्थिरांक की गणना को भी समायोजित कर सकता है और इसलिए Field8
बना सकता है नतीजतन। हालाँकि मेरा मानना है कि इस तरह की गणना क्लाइंट पर की जानी चाहिए और MongoDB को वह करने देना चाहिए जो सर्वर पर सबसे अच्छा करता है।
चरण 2:Field8
जोड़ने के लिए कुल का उपयोग करें फ़ील्ड
उस अतिरिक्त फ़ील्ड को बनाने के बाद daysInWeek
फिर आप एक एकत्रीकरण पाइपलाइन का निर्माण कर सकते हैं जो के कोहोर्ट का उपयोग करके नए चरों को प्रोजेक्ट करता है। अंकगणितीय संचालिका
गणना करने के लिए (फिर से, आवेदन परत पर ऐसी गणना करने की सिफारिश करेगा)। अंतिम प्रक्षेपण परिकलित फ़ील्ड का उत्पाद होगा जिसे आप फिर से करने के लिए समग्र परिणाम कर्सर का उपयोग कर सकते हैं और Field8
जोड़ सकते हैं प्रत्येक दस्तावेज़ के साथ संग्रह के लिए:
var pipeline = [
{
"$project": {
"C1": {
"$add": [
10,
{ "$multiply": [ "$Field3", 0.03 ] }
]
},
"C2": {
"$cond": [
{ "$eq": [ "$Field2", 1 ] },
1,
0.03
]
},
"C3": "$daysInWeek",
"C4": {
"$cond": [
{ "$eq": [ "$Field2", 1 ] },
{ "$pow": [ "$Field4", -0.6 ] },
1
]
}
}
},
{
"$project": {
"Field8": { "$multiply": [ "$C1", "$C2", "$C3", "$C4" ] }
}
}
],
counter = 0,
bulkUpdateOps = [];
db.collection1.aggregate(pipeline).forEach(function(doc) {
bulkUpdateOps.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": {
"$set": { "Field8": doc.Field8 }
}
}
});
counter++;
if (counter % 500 == 0) {
db.collection1.bulkWrite(bulkUpdateOps);
bulkUpdateOps = [];
}
});
if (counter % 500 != 0) { db.collection1.bulkWrite(bulkUpdateOps); }
MongoDB के लिए >=2.6
और <=3.0
, बल्क ऑपरेशन API
का उपयोग करें जहां आपको कर्सर के का उपयोग करके संग्रह को पुनरावृत्त करने की आवश्यकता है forEach()
विधि, संग्रह में प्रत्येक दस्तावेज़ को अद्यतन करें।
उपरोक्त एकत्रीकरण पाइपलाइन से कुछ अंकगणितीय ऑपरेटर MongoDB >=2.6
में उपलब्ध नहीं हैं और <=3.0
इसलिए आपको गणनाएं के भीतर करने की आवश्यकता होगी। forEach()
पुनरावृति।
प्रत्येक अपडेट को बल्क में बंडल करके सर्वर लिखने के अनुरोधों को कम करने के लिए बल्क एपीआई का उपयोग करें और प्रसंस्करण के लिए संग्रह में प्रत्येक 500 दस्तावेज़ों में केवल एक बार सर्वर को भेजें:
var bulkUpdateOps = db.collection1.initializeUnorderedBulkOp(),
cursor = db.collection1.find(), // cursor
counter = 0;
cursor.forEach(function(doc) {
// computations
var c1, c2, c3, c4, Field8;
c1 = 10 + (0.03*doc.Field3);
c2 = (doc.Field2 == 1) ? 1: 0.03;
c3 = 7 - (doc.Field5.match(new RegExp(".", "g")) || []).length;
c4 = (doc.Field2 == 1) ? Math.pow(doc.Field, -0.6) : 1;
Field8 = c1*c2*c3*c4;
bulkUpdateOps.find({ "_id": doc._id }).updateOne({
"$set": { "Field8": Field8 }
});
if (counter % 500 == 0) {
bulkUpdateOps.execute();
bulkUpdateOps = db.collection1.initializeUnorderedBulkOp();
}
})
if (counter % 500 != 0) { bulkUpdateOps.execute(); }