Jake Wood
Jake Wood

Reputation: 107

Count Undefined with MongoDB and Nodejs

Problem

Node.js MongoDB library consistently returns undefined for collection.count({}). This question has been posted and answered numerous times, and I've been sure to go through all previous solutions, but none seem to work, and I always get undefined.

As a background to the question, I am making a Job Automator, and before adding a new job, I want to make sure that 0 records already exist in the database that have the same name as the new job being added (i.e. names are unique). EDIT: There are a few cases where I do want to allow duplicates, so I don't want using indexing and dis-allow duplicates at the DB level.

Code

In this case, the console.log() inside count just prints undefined. In this case, I have put in an empty query string as part of debugging (not currently testing for name collisions).

add: function(io, newJob)
    {
    //mc is where require('mongodb').MongoClient is saved
    //connectionString contains a valid connection string
    //activeCollection contains the name of the collection
    //(I am sure mc, connectionString and activeCollection are valid)
    //I know this as I have used them to insert documents in previous parts
    mc.connect(connectionString, function(err,db)
        {
        if(err)
            throw err;
        else
            {
            db.collection(activeCollection, function(err,collection)
                {
                if(err)
                    throw err;
                //Start of problematic part
                //See also "What I've tried" section
                collection.count({},function(err,count)
                    {
                    console.log(count);
                    });
                //End of problematic part
                //Omitting logic where I insert records for brevity,
                //as I have confirmed that works previously.
                });
            }
        db.close();
        });
    }

What I've tried

I've read the previous questions, and replaced the content between //Start of problematic part and //End of problematic part in the previous code block with the following blocks:

Fully breaking out the callback (also prints undefined):

function countDocs(callback)
    {
    collection.count({},function(err, count)
        {
        if(err)
            throw err;
        callback(null, count);
        }
    }

countDocs(function(err,count)
    {
    if(err)
        throw err;
    console.log(count);
    });

I've even tried things I know wouldn't work

var count = collection.count({});

NEW (1/28/16)

It was a little sloppy of me to not check the error in my count(), so I added a if(err)console.log(err); into the count() block and it turns out the error is:

{ [MongoError: server localhost:27017 sockets closed] 
name: 'MongoError', 
message: 'server localhost 27017 sockets closed' }

Which I don't really understand because in other sections of code, I am able to use the same connect() and collection() calls and make inserts into the DB just fine. Any insight based on this?

Any help would be much appreciated!

Upvotes: 1

Views: 989

Answers (2)

Paul Grimshaw
Paul Grimshaw

Reputation: 21024

You can use collection.find().toArray(function(err,documents) { ...});, which returns an empty array if no documents match your query. Checking the length property of the array should be equivalent to what you are trying to achieve with count().

More info in the docs: https://mongodb.github.io/node-mongodb-native/api-generated/cursor.html#toArray

Upvotes: 0

Michel Floyd
Michel Floyd

Reputation: 20227

Let's deal with the intent of the question:

I am making a Job Automator, and before adding a new job, I want to make sure that 0 records already exist in the database that have the same name as the new job being added (i.e. names are unique).

Rather than labor through javascript, just set a unique index on the name key. In mongo:

db.collection.ensureIndex( { name: 1 }, { unique: true } )

Then when you insert a document use a try/catch block to catch any attempt to create a document with a duplicate name.

Upvotes: 1

Related Questions