How to check if a collection exists in Mongodb native nodejs driver?
node.jsMongodbNode Mongodb-Nativenode.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
}
}