MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

mongodb कुल क्वेरी $sum . का उपयोग करने पर उचित राशि नहीं लौटा रही है

आपके वर्तमान स्कीमा में 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
}


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. सरणी फ़ील्ड में उप-दस्तावेज़ों को कैसे क्रमबद्ध करें?

  2. $प्रोजेक्ट चरण में $in ऑपरेटर का उपयोग करके फ़िल्टर सरणी

  3. मोंगोडब में किसी फ़ील्ड का केवल मान कैसे लौटाएं?

  4. पाइमोंगो का उपयोग करके केवल पढ़ने के लिए कनेक्शन कैसे प्राप्त करें

  5. मैं मोंगोडीबी से जेड तक ऑब्जेक्ट पर कैसे भेजूं?