dany
dany

Reputation: 1871

Taking sum/average of columns in mongoosejs

I have a MongoDB collection "Marks" with fields student_id,Subject,Mark. I want to the average value of marks scored by a particular student. My project is in NodeJs and I am using MongooseJS for object modeling. How to query the this using MOngooseJS?

EXAMPLE

     Student_id   Subject  Mark
     111          AAA      9
     111          BBB      5
     111          CCC      7
     222          AAA      10
     222          CCC      6
     222          BBB      8

I want average of marks scored by student(id) 111 i.e((9+5+7)/3)=7)

Upvotes: 2

Views: 6211

Answers (2)

JohnnyHK
JohnnyHK

Reputation: 311855

If you're using MongoDB 2.2 you can use the aggregation framework for this:

var Mark = mongoose.model('mark', new Schema({
    Student_id: Number,
    Subject: String,
    Mark: Number
}));

Mark.aggregate([
        { $group: {
            _id: '$Student_id',
            markAvg: { $avg: '$Mark'}
        }}
    ], function (err, results) {
        if (err) {
            console.error(err);
        } else {
            console.log(results);
        }
    }
);

Output:

[ { _id: 222, markAvg: 8 }, { _id: 111, markAvg: 7 } ]

Upvotes: 12

Tigraine
Tigraine

Reputation: 23648

This sounds like the poster child example of a Map/Reduce operation in MongoDB.

What you want to do is first run a map step where you emit all grades that belong to student id 111. Then you run the reduce step where you average these.

The monogdb code should look similar to this:

var map = function() {
  emit(this.Student_id, this.Mark);
}
var reduce = function(key, values) {
  var result = { studentid: key, mark_sum: 0, count: 0, avg_mark: 0 };
  values.forEach(function(v) {
    r.mark_sum += v;
    r.count += 1;
  });
  return r;
}

var finalize = function(key, value) {
  if (value.count > 0) {
    value.avg_mark = value.mark_sum / value.count;
  }
  return value;
}

And the execution of the mapReduce in Mongo syntax:

var command = db.runCommand( { mapreduce:"<your collection>",
                  map: map,
                  reduce: reduce,
                  query: { Student_id: 111 },
                  out: { reduce: "session_stat" },
                  finalize: finalize
                });

The result of the map_reduce is written to session_stat. Where you can query it.

To see how to use MapReduce in Mongoose please look at this Question: mongoose mapreduce()

Upvotes: 2

Related Questions