Skip to content

Instantly share code, notes, and snippets.

@ronalstal
Created November 15, 2012 18:55
Show Gist options
  • Save ronalstal/4080463 to your computer and use it in GitHub Desktop.
Save ronalstal/4080463 to your computer and use it in GitHub Desktop.
MongoDB course m0101 homework 3-2 for node.js
var mongodb = require('mongodb');
var _ = require('underscore');
var db = mongodb.Db('school', new mongodb.Server('localhost', 27017), {safe: true});
db.open(function(err, client) {
if(err) {
console.log('Error opening connection' + err);
}
console.log('db opened');
var collection = new mongodb.Collection(client, 'students');
// find all students that have at least one homework score
// ( note: all stundents have, so this query is not really needed )
var query = {"scores.type":"homework"};
// no need for sorting
var options = {};
collection.find(query,options).toArray(function(err, docs) {
if (err) {
console.log(err);
}
// loop all docs (students)
_.each(docs, function(doc) {
// loop the students' scores and find the lowest homework
var lowScore = 9999.9;
for ( var i=0; i<doc.scores.length; i++ ) {
if ( doc._id == 100 && doc.scores[i].type == "homework" ) { console.log("id 100 hw "+doc.scores[i].score); }
if ( doc.scores[i].type == "homework"
&& doc.scores[i].score < lowScore ) {
lowScore = doc.scores[i].score;
}
}
if ( doc._id == 100 ) { console.log("lowScore "+lowScore); }
// update student pulling the homework-score with the found lowest score
collection.update({ "_id":doc._id },
{ $pull : { "scores" : {
$and: [ {"type":"homework"}, { "score":lowScore} ]
} } },
{ "safe":true },
function( err, result ) {
if (err) {
console.log(err);
}
// if (doc._id == 100) { console.log("id 100 updated "+result); }
// console.log("callback "+result);
} // update callback
); // update
}); // each student
console.log('done');
client.close();
}); // find()
}); // db.open()
// for node.js
// homework 3-1 without removing the lowest scores
// see hw31.js for "normal" way
var mongodb = require('mongodb');
var _ = require('underscore');
var db = mongodb.Db('school', new mongodb.Server('localhost', 27017), {safe: true});
db.open(function(err, client) {
if(err) {
console.log('Error opening connection' + err);
}
console.log('db opened');
var Students = new mongodb.Collection(client, 'students');
console.log('Students collection');
// set up the stuff for mapReduce:
// ono query
var qry = {};
// per student map the score and the _id of the document
var mapf = function() {
var low = 0;
// loop the scores and emit one record per score (all types !!)
for ( var i=0; i<this.scores.length; i++ ) {
low = ( this.scores[i].type == "homework" ? this.scores[i].score : 9999.9 );
emit( this._id,
{
student_id: this._id,
name: this.name,
count: 1,
sum: this.scores[i].score,
low: low,
average: 0
}
); // emit
}; // loop scores
}; // mapf
// reduce this to one record per student
// remembering the lowest homework score; count and sum all scores (for the average)
var reducef = function(key, values) {
var r = {
student_id: key,
name: null,
count: 0,
sum: 0,
low: 9999,
average: 0
}
// loop all values emitted by mapf
values.forEach(function(v) {
r.student_id = v.student_id;
r.name = v.name;
r.count += v.count;
r.sum += v.sum;
r.low = ( v.low < r.low ? v.low : r.low );
});
return r;
};
// this will be called once per student:
// compute average without lowest score
var finalizef = function(key, value) {
value.average = ( value.count == 1 ? 0.0 :
(value.sum - value.low) / (value.count - 1) );
return value;
};
// call it
Students.mapReduce(mapf, reducef,
{
query: qry,
finalize: finalizef,
out: { replace: "students_hw31_mr" }
},
function(err, rsltColl) {
if (err) {
console.log(err);
}
console.log('mapReduce callback...');
// compute the result for HW 3-1:
// -- find the student_id with the highest average
rsltColl.find({},{},{sort:[["value.average","desc"]],limit:1})
.toArray(function(err, docs) {
if (err) {
console.log(err);
}
console.log('and the answer is: ' + docs[0].value.student_id);
client.close();
}); // find toArray result
} // mapReduce callback
); // mapReduce()
}); // db.open()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment