node.js MongoDB query not returning results

2020-06-09 05:57发布

问题:

I was playing around with mongodb and entered some test data {name:"david"} into the 'users' collection. I verified that the data was in MongoDB using the mongo shell by typing

db.users.find()

result:

{ "name":"david" }

In node.js script, the following code:

db.open(function(err, db) {
    if (!err) {
        console.log("db opened!");
    }
    else {
        console.log(err);
    }
    db.collection('users', function(err, collection) {
        collection.find({}, function(err, cursor) {
            cursor.each(function(err, item) {
                console.log(item);
            });
        });
    });
    db.close();
});

does not return any results

I don't see anything wrong, and no err returns. Please advise

回答1:

You're actually closing your database connection before data from the collection has returned.

db.collection('users', function(err, collection) {
  collection.find({}, function(err, cursor) {
    cursor.each(function(err, item) {
      console.log(item);
    });

    // our collection has returned, now we can close the database
    db.close();
  });
});


回答2:

As CJohn states correctly you are closing the DB connection BEFORE you retrieve the data. I know it doesn't look like it but this is the case with Node structure and callbacks. The code to correctly handle this is:

db.open(function(err, db) {
    if (err) return console.log('error opening db, err = ', err);

    console.log("db opened!");

    db.collection('users', function(err, collection) {
        if (err) return console.log('error opening users collection, err = ', err);

        collection.find({}, function(err, cursor) {
            if (err) return console.log('error initiating find on users, err = ', err);

            cursor.each(function(err, item) {
                // watch for both errors and the end of the data
                if (err || ! item) {
                    // display (or do something more interesting) with the error
                    if (err) console.log('error walking data, err = ', err);

                    // close the connection when done OR on error
                    db.close();

                    return;
                }
                console.log(item);
            });
        });
    });
});


回答3:

This pattern is working fine in my node/mongo sample. The function is passed a callback which takes err, collection. It gets the 'users' collection and if successful, calls find against the collection and converts it to an array but you can iterate on the cursor as well.

Inside the db.collection and the connection.find calls, you're not checking for err and handling. You're only doing it on the open call.

Also, you shouldn't call db.close() especially if you're opening with connection pool option (you don't want to open and close the connection on every call). If you did want to close, then close inside the callback.

Something like:

var server = new Server(host, port, {auto_reconnect: true, poolSize: 5}, {});

MyStore.prototype.getUsers = function(callback) {
server.open(function(err, db) {
    if (err) {
        callback(err);
    }
    else {
        db.collection('users', function(err, collection) {
            if( err )
                callback(err);
            else {
                collection.find().toArray(function(err, users) {
                    if (err) {
                        callback(err)
                    } else {
                        callback(null, users);
                    }
                });
            }
        }
    }});

Here's another tutorial on node + mongo that may help: http://howtonode.org/express-mongodb



回答4:

Try upgrading your node to latest version.

sudo npm cache clean -f
sudo npm install -g n
sudo n stable

version 0.4 may not work properly.