How to check if a collection exists in Mongodb native nodejs driver?

node.jsMongodbNode Mongodb-Native

node.js Problem Overview


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.

node.js Solutions


Solution 1 - node.js

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
        }
    });

Solution 2 - node.js

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.

Solution 3 - node.js

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

Solution 4 - node.js

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

Solution 5 - node.js

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;
    }));
  });
}

Solution 6 - node.js

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")  
  }); 
});

Solution 7 - node.js

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

Solution 8 - node.js

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+"");

});

Solution 9 - node.js

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):
   ...

Solution 10 - node.js

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

Solution 11 - node.js

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
}

Solution 12 - node.js

/* 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
}

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNasser TorabzadeView Question on Stackoverflow
Solution 1 - node.jsJohnnyHKView Answer on Stackoverflow
Solution 2 - node.jsChrisVView Answer on Stackoverflow
Solution 3 - node.jsDerickView Answer on Stackoverflow
Solution 4 - node.jsRobertoView Answer on Stackoverflow
Solution 5 - node.jsweekensView Answer on Stackoverflow
Solution 6 - node.jsroscoe_xView Answer on Stackoverflow
Solution 7 - node.jsMattCochraneView Answer on Stackoverflow
Solution 8 - node.jsJaY KuMaRView Answer on Stackoverflow
Solution 9 - node.jsdimidView Answer on Stackoverflow
Solution 10 - node.jsLincolnView Answer on Stackoverflow
Solution 11 - node.jsBigMan73View Answer on Stackoverflow
Solution 12 - node.jsanteloveView Answer on Stackoverflow