0

From homework 2_2 of the M101JS course at university.mongodb.com.

Write a program that finds the document with the highest recorded temperature for each state, and adds a "month_high" field for that document, setting its value to true.

The following code should work to update the correct doc in the collection adding "month_high". And the problem is here:

//db.collection('data').update(query, setMonthHigh, function(err, updated) {//OK
db.collection('data').update(query, doc, function(err, updated) {// NOT OK, dunno why

The 2nd update line does not save anything. But if I use the commented update above, it works.

Does anyone have an idea why the 2nd update line isn't working (the one that replaces the whole doc)?

var MongoClient = require('mongodb').MongoClient;

MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {

if(err) throw err;

var options = { 'sort' : [ ['State', 1], ['Temperature', -1] ]};
var lastDoc = null;
var setMonthHigh = {'$set':{'month_high':true}};

var cur = db.collection('data').find({}, {},options);
//var cur = db.collection('data').find({'month_high':true}, {},options);

cur.each(function(err, doc) {
    if(err) throw err;

    if(doc == null) {
        console.log("Document done");
        //return db.close();
        db.close();
        process.exit(0);
    }

    var query = {'_id' : doc._id};

    //db.collection('data').update({'month_high':true}, {$unset:{'month_high':1}}, function(err, updated) {});
    //console.dir(doc);

    if ( ( lastDoc != null && lastDoc.State != doc.State ) ||
        lastDoc == null )
    {
        doc['month_high'] = 'true';
        //db.collection('data').update(query, setMonthHigh, function(err, updated) {//OK
        db.collection('data').update(query, doc, function(err, updated) {
            // NOT OK, dunno why
            if(err) throw err;
            console.dir("Update "+updated);
        });
        console.dir(doc);
    }
    lastDoc = doc;
});
});

Also, I'm told that using process.exit(0) is a bad hack, but it was the only way I could exit the code without throwing exceptions on return db.close();. If anyone knows a way to exit the code gracefully, that would be great too.

Quality Catalyst
  • 6,531
  • 8
  • 38
  • 62

1 Answers1

0

First of all, you have made a mistake in part of your code responsible for updating a database. db.collection('data').update is an asynchronous function. It means that you cannot execute db.close() without knowing if all updates have been completed. For more details please read: How can I use a cursor.forEach() in MongoDB using Node.js?

Both updates works. However there is one difference between two of them:

  1. db.collection('data').update(query, setMonthHigh, function(err, updated) updates records with a new field: 'month_high': true <- boolean value

    Query to find these records is: db.data.find({'month_high': true})

  2. db.collection('data').update(query, doc, function(err, updated) updates records with a new field: 'month_high': 'true' <- string value

    Query to find these records is: db.data.find({'month_high': 'true'})

Your updated code:

Before run it, first install async library (npm install async)

var async = require('async');
var MongoClient = require('mongodb').MongoClient;

MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {

  if(err) throw err;

  var q = async.queue(function (doc, callback) {
    db.collection('data').update({_id: doc._id}, doc, callback);
  }, Infinity);

  var options = { 'sort' : [ ['State', 1], ['Temperature', -1] ]};
  var lastDoc = null;

  var cur = db.collection('data').find({}, {},options);

  cur.each(function(err, doc) {
    if(err) throw err;
    if(doc === null) return;

    if ( ( lastDoc !== null && lastDoc.State !== doc.State ) ||
        lastDoc === null )
    {
        doc['month_high'] = true;
        q.push(doc, function(err, updated) {
            if(err) throw err;
            console.log("Update "+updated);
        });
    }
    lastDoc = doc;

  });

  q.drain = function() {
    if (cur.isClosed()) {
      console.log('Document done');
      db.close();
    }
  }

});
Community
  • 1
  • 1
PiKos
  • 1,344
  • 1
  • 16
  • 15