57

I need to check if a collection exists on a certain database and create it if it doesn't. I know that

db.createCollection(collName, {strict:true}, function(error, collection))

checks for existance of collection collName before creating it and sets error object. but I need an independent function to check that.

2
  • more information required: which connector library are you using, and have you checked its manual/api documents? Commented Jan 9, 2014 at 15:21
  • @Mike'Pomax'Kamermans I'm using mongo-native driver library, and I couldn't find such functionality in it's API documents. Commented Jan 9, 2014 at 15:38

12 Answers 12

68

The collectionNames method of the native driver's Db object accepts an optional collection name filter as a first parameter to let you check the existence of a collection:

db.collectionNames(collName, function(err, names) {
    console.log('Exists: ', names.length > 0);
});

In the 2.x version of the MongoDB native driver, collectionNames has been replaced by listCollections which accepts a filter and returns a cursor so you would do this as:

db.listCollections({name: collName})
    .next(function(err, collinfo) {
        if (collinfo) {
            // The collection exists
        }
    });
Sign up to request clarification or add additional context in comments.

2 Comments

This should be the accepted answer as it is the only answer that actually deals with node.js (like OP asked for).
also one liner db.listCollections({ name: colName }).hasNext()
25

Using mongo-native driver and Node.js 7.6+, I use the following:

const collections = await db.collections();
if (!collections.map(c => c.s.name).includes(collName)) {
    await db.createCollection(collName);
}

EDIT

As @MattCochrane mentions, collection.s.name is no longer available; as @JohnnyHK and @weekens point out, the correct way is to use the listCollections() method:

const client = new MongoClient(connectionString, { useUnifiedTopology: true });
await client.connect();
const collections = await client.db().listCollections().toArray();
const collectionNames = collections.map(c => c.name);

listCollection() takes an optional filter.

3 Comments

Just tested this Node v8.11.4 - mongodb - 3.1.10: and it works great!
You could make this a little shorter with some() instead of map and includes developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
This no longer works in mongodb 3.6.0, the name property is not available on collection.s . A lesson for me.. I should have known better than to use what is clearly not intended to be a public interface.
19

In MongoDB 3.0 and later, you have to run a command to list all collections in a database:

use test;
db.runCommand( { listCollections: 1 } );

Although querying system.namespaces will still work when you use the default storage engine (MMAPv1), it is not guaranteed to work for other engines, such as WiredTiger.

Before MongoDB 3.0 you need to do the following:

You can query the system.namespaces collection:

use test;
db.system.namespace.find( { name: 'test.' + collName } );

Like in:

db.system.namespaces.find( { name: 'test.testCollection' } );

Which returns:

{ "name" : "test.testCollection", "options" : { "flags" : 1 } }

Or of course, nothing.

See also: https://github.com/mongodb/specifications/blob/master/source/enumerate-collections.rst

5 Comments

in mongo-native: db.collection('system.namespaces').find().toArray(function(err, items) {})
Late to the party, but I think my answer below (stackoverflow.com/a/40141321/446717) has a more direct and clean approach to get that info
None of this in the answer is available in the native node.js lib. Only working thing is what Nasser provided.
As of today, this answer no longer holds valid, ` db.listCollections({name: collName}) .next(function(err, collinfo) { if (collinfo) { // The collection exists } }); ` is a valid answer from this answer
how do you get this db object in nodejs?
6

Since MongoDB 3.0 you can simply run:

db.getCollectionNames()

which returns an array with the names of all the collections on current database:

[ "employees", "products", "mylogs"]

check Mongo DB Documentation, or you could also use db.getCollectionInfos() if you need more info about each collection

5 Comments

The method getCollectionNames() is not available in node.js native lib.
Hey, but I'm using it from mongodb lib, which is the one that manages the mongo database @DanFromGermany
There is Db.collectionNames() in the older API available but not getCollectionNames() at all.
Which version of MongoDB are you using, this getCollectionNames() exists in MongoDB 3.0
Dude, the latest node driver for mongo is 2.2 (link). 3.0 does not even exist.
5

There is now a listCollections method in Node.js native driver. It returns information on all collections in current database. You can use it to check if a given collection is there:

collectionExists = function(name, cb) {
  mongoDb.listCollections().toArray(function(err, collections) {
    if (err) return cb(err);

    cb(null, collections.some(function(coll) {
      return coll.name == name;
    }));
  });
}

3 Comments

@NikolaLukic in cb function, first argument is an error (null if no error), second argument is boolean, that is true if collection exists and false if not. collectionExists function can also be implemented with promises instead of callbacks.
I already have same info with listCollections().toArray . I need to write simple function like : isExist (name ) , and use it like if ( isExist('mycollection') == true) { doSomething(); } Maybe i will need async methods...
@NikolaLukic, yes, you will probably end up with if (await isExist('mycollection')) or if (yield isExist('mycollection')). There is no other way to make asynchronous method look like synchronous one. I guess, == true is redundant.
5

If you use mongodb 3.1.10. This is how to check if collections exist.

MongoClient.connect(url, { useNewUrlParser: true }, function(err, client) {
  if (err) throw err;

  var dbo = client.db("dbname");
  dbo.listCollections().toArray(function(err, items){
    if (err) throw err;

    console.log(items); 
    if (items.length == 0)
        console.log("No collections in database")  
  }); 
});

Comments

3

An updated answer which works with 3.6.* releases.

/**
 * Checks if a collection exists in a mongo database.
 * 
 * @param db a mongo db object.  eg.
 *    client = await MongoClient.connect(uri);
 *    db = client.db();
 * @param collectionName the name of the collection to search for
 * @returns {Promise<boolean>}
 */
async function doesCollectionExistInDb(db, collectionName) {
  const collections = await db.collections();
  return collections.some(
      (collection) => collection.collectionName === collectionName
  );
}

...

if (await doesCollectionExistInDb(db, 'products')) {
   // Do something, such as create a new collection
}

The collection.collectionName is part of the documented collection api as can be found here: http://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html#collectionName

1 Comment

This worked for me in 2021, great clean solution!
3

For nodejs with mongodb library (v 3.6.3) that's the only way I got it working:

const collectionName = 'products'
const exists = (await (await db.listCollections().toArray()).findIndex((item) => item.name === collectionName) !== -1)
console.log(exists)

Hope that helps others

Comments

3

actually, this works for me

  await db.createCollection(name, function (err, res) {
    if (err) {
        //console.log(err);
        if (err.codeName =="NamespaceExists") {
            console.log("Already Exists Collection  : " + name + "");
            return;
        }
    }
    console.log("Collection created! : "+name+"");

});

Comments

3

An async TypeScript function:

/**
 * Predicate function that checks if a collection exists in a given MongoDB database
 *
 * @param {Db} db Mongo database instance
 * @param {string} collectionName Name of collection
 *
 * @returns {boolean} true if collection exists, false otherwise
 */
export const doesCollectionExist = async (db: Db, collectionName: string): Promise<boolean> => {
  const cursor = db.listCollections({ name: collectionName })
  const result = await cursor.hasNext()
  await cursor.close()

  return result
}

Comments

1

The question refers to the native driver, but I got here searching how to do this in pymongo. Usually pymongo's api is identical to the JS api, but in this case collection_names doesn't have an argument for the collection's name (as in JohnnyHK's answer), but rather the first argument is a boolean (whether to include system collections). Since a string evaluates to True, this can be confusing. So I hope this helps future readers:

import pymongo

cl = pymongo.MongoClient()
db = cl['my-db']
if 'my-col' in db.collection_names(False):
   ...

Comments

0
/* set database */
let db          = client.db( 'crud' )

/* set collection */
let collection  = db.collection( 'categories' )

/* set query */
collection.find( {} ).toArray( ( err, result ) => {

if ( result.length > 0 )
{
    console.log("Exist");
}
else
{
    console.log("Not Exist");

    // create collection
}

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.