Search code examples
javascriptnode.jsmongodbcursor

When do you call db.close() when using cursor.forEach()?


If using .toArray(), I know you could use db.close() inside the callback like so:

db.collection('grades').find(query).toArray(function(err, docs) {
  if (err) throw err;
  console.dir(docs);
  db.close();
});

But what if you need to iterate over the array? It seems excessive to 1) iterate through the cursor to construct the array and then 2) iterate over the array to do your work. So I was thinking that it'd be good to use cursor.forEach().

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

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

  var cursor = db
                .collection('data')
                .find({})
                .sort({State: 1, Temperature: -1});

  var prevState = '';
  var curr;

  cursor.forEach(function(doc) {
    if (doc.State === prevState) return;

    db.collection('data').update(doc, { $set: { month_high: true}});
    prevState = doc.State;
  });

  db.close();
});

However, this gives me an error:

~/code/m101js $ node test.js
/Users/azerner/code/node_modules/mongodb/lib/utils.js:97
    process.nextTick(function() { throw err; });
                                        ^
TypeError: undefined is not a function
    at /Users/azerner/code/node_modules/mongodb/lib/cursor.js:527:15
    at handleCallback (/Users/azerner/code/node_modules/mongodb/lib/utils.js:95:12)
    at /Users/azerner/code/node_modules/mongodb/lib/cursor.js:493:22
    at handleCallback (/Users/azerner/code/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:234:5)
    at /Users/azerner/code/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:533:22
    at queryCallback (/Users/azerner/code/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:167:20)
    at Callbacks.flush (/Users/azerner/code/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:86:7)
    at Server.destroy (/Users/azerner/code/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:694:41)
    at Server.close (/Users/azerner/code/node_modules/mongodb/lib/server.js:344:17)
    at Db.close (/Users/azerner/code/node_modules/mongodb/lib/db.js:273:19)
~/code/m101js $ node test.js
/Users/azerner/code/node_modules/mongodb/lib/utils.js:97
    process.nextTick(function() { throw err; });
                                        ^
TypeError: undefined is not a function
    at /Users/azerner/code/node_modules/mongodb/lib/cursor.js:527:15
    at handleCallback (/Users/azerner/code/node_modules/mongodb/lib/utils.js:95:12)
    at /Users/azerner/code/node_modules/mongodb/lib/cursor.js:493:22
    at handleCallback (/Users/azerner/code/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:234:5)
    at /Users/azerner/code/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:533:22
    at queryCallback (/Users/azerner/code/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:167:20)
    at Callbacks.flush (/Users/azerner/code/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:86:7)
    at Server.destroy (/Users/azerner/code/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:694:41)
    at Server.close (/Users/azerner/code/node_modules/mongodb/lib/server.js:344:17)
    at Db.close (/Users/azerner/code/node_modules/mongodb/lib/db.js:273:19)
~/code/m101js $

It seems to be all library code and I'm not really sure how to debug it. But it looks like the problem is in db.close().

  1. Is this so?
  2. If so, then where else would I put db.close()?

Solution

  • The issue is that db.close() was being called, and then I was trying to interact with the database. You can't interact with the database when the connection has already been closed.

    The reason why my code was trying to interact with the database after the connection was closed is because the .update() is asynchronous.

    Using async.each worked for me. async.each gives you a callback to run after everything in the collection has been iterated through. I called db.close() in that callback, which is the time when I wanted to close the connection to the database.