Mongodb total query does not return the correct amount when using $ sum

I have a collection student with documents in the following format: -

{
 _id:"53fe74a866455060e003c2db",
 name:"sam",
 subject:"maths",
 marks:"77"
}
{
 _id:"53fe79cbef038fee879263d2",
 name:"ryan", 
 subject:"bio",
 marks:"82"
}
{
 _id:"53fe74a866456060e003c2de",
 name:"tony",
 subject:"maths",
 marks:"86"
}

I want to get the total grades of all students with subject = "maths". So I have to get 163 as a sum.

db.students.aggregate([{ $match : { subject : "maths" } },
{ "$group" : { _id : "$subject", totalMarks : { $sum : "$marks" } } }])

Now I have to get the following result -

{"result":[{"_id":"53fe74a866455060e003c2db", "totalMarks":163}], "ok":1}

But I get -

{"result":[{"_id":"53fe74a866455060e003c2db", "totalMarks":0}], "ok":1}

Can someone point out what I can do wrong here?

+5
source share
2 answers

marks , . , MapReduce , JavaScript, parseInt(), . , .


1: ( )

, , . , mongodb 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) } }
    );
});

db , mongo bulk updates :

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, JavaScript parseInt().

MapReduce , . marks subject subject marks. JavaScript 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
}
+4

0:

  1. , , , .

    , .

  2. $ sum.

    db.c1.aggregate([{ $group: { _id: "$item", price: { $sum: "$price" }, count: { $sum: 1 } } }])

    , "$ price", "Price".

  3. , - :

    .

    - "$ price" !!! " $" .

0

All Articles