ml242
ml242

Reputation: 109

NodeJS Error with stock Mongodb Adapter: Connection Closed By Application

I'm having a weird issue with MongoDB. My database collection is closing, which I suppose is what it's supposed to do (I'm following along from the mongo boilerplate) BUT I see no reason why the docs would be null value. I've checked this every way I can think of, but I don't quite understand the cursor object.

Console.logging it seems to give me a bunch of native mongo properties ( which look like functions ie each, toArray, etc) so it seems right, but it's not a regular object with a data field that I can see.

After it hits that if block with the if(docs==null), the connection gets closed and it will not execute the each block in the else if.

Ideally if there was a way to help troubleshoot or figure out how to make this execute that would be great.

More background: in the mongo shell I can ask for use weather // no issues and get the results of the data object which is 3000 records with an empty find();

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

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


    if(err){
     console.log("line 7" + err);   
    }

    var query = {};
    var projection = { 'State' : 1, 'Temperature' : 1 };
    var cursor = db.collection('data').find(query, projection);
    console.log("cursor" + cursor); // [object Object]

    var state = '';
    var operator = {'$set' : {'month_high' : true } };

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

        if (doc == null) {
            console.log("docs have value:" + doc); //NULL VALUE so will close on line 23
            return db.close();
        } else if (doc.State !== state) {
            // first record for each state is the high temp one
            state = doc.State;

            db.collection('data').update( {'_id':doc._id}, operator, function(err, updated) {
                if (err) console.log(err);
                // return db.close(); ?
            });

        }   

    });


});


{ [MongoError: Connection Closed By Application] name: 'MongoError' } //doh
{ [MongoError: Connection Closed By Application] name: 'MongoError' } //doh
{ [MongoError: Connection Closed By Application] name: 'MongoError' } //doh

Upvotes: 2

Views: 566

Answers (1)

anthonyserious
anthonyserious

Reputation: 1946

Figuring out when to call db.close() can be a bit messy. Here it is rewritten with find().toArray() plus some logic to test when you're updating the last matched doc. This works for me.

var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var Q = require('q');

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

  var query = {};
  var projection = { 'State' : 1, 'Temperature' : 1 };

  var state = '';
  var operator = {'$set' : {'month_high' : true } };

  var promises = [];

  db.collection('data').find(query, projection).toArray(function(err, docs) {
    assert.equal(null, err);

    docs.forEach(function(doc, index, arr) {
      var deferred = Q.defer();
      promises.push(deferred.promise);
      if (null !== doc && state !== doc.State) {
        db.collection('data').update( {'_id':doc._id}, operator, function(err, updated) {
          assert.equal(null, err);
          console.log("Updated "+updated+" documents.");
          deferred.resolve();
        });
      } else {
        deferred.resolve();
      }
    });
    Q.all(promises).done(function() {
      console.log("closing");
      db.close()
    });
  });
});

EDIT: Added Q since db.close() was still called prematurely in some cases.

Upvotes: 1

Related Questions