Node.js 如何检查Mongodb本机nodejs驱动程序中是否存在集合?

Node.js 如何检查Mongodb本机nodejs驱动程序中是否存在集合?,node.js,mongodb,node-mongodb-native,Node.js,Mongodb,Node Mongodb Native,我需要检查某个数据库上是否存在集合,如果不存在,则创建集合。我知道 db.createCollection(collName, {strict:true}, function(error, collection)) 在创建集合之前检查集合collName是否存在,并设置error对象。但我需要一个独立的函数来检查这一点。在MongoDB 3.0及更高版本中,您必须运行命令来列出数据库中的所有集合: use test; db.runCommand( { listCollections: 1 }

我需要检查某个数据库上是否存在集合,如果不存在,则创建集合。我知道

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

在创建集合之前检查集合
collName
是否存在,并设置
error
对象。但我需要一个独立的函数来检查这一点。

在MongoDB 3.0及更高版本中,您必须运行命令来列出数据库中的所有集合:

use test;
db.runCommand( { listCollections: 1 } );
尽管在使用默认存储引擎(MMAPv1)时,查询
system.namespace
仍能工作,但不能保证它适用于其他引擎,如WiredTiger

在MongoDB 3.0之前,您需要执行以下操作:

use test;
db.runCommand( { listCollections: 1 } );
您可以查询
系统名称空间
集合:

use test;
db.system.namespace.find( { name: 'test.' + collName } );
db.collectionNames(collName, function(err, names) {
    console.log('Exists: ', names.length > 0);
});
例如:

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

{ "name" : "test.testCollection", "options" : { "flags" : 1 } }
当然,也没什么

另请参见:

本机驱动程序的
Db
对象的方法接受可选的集合名称筛选器作为第一个参数,以允许您检查集合是否存在:

use test;
db.system.namespace.find( { name: 'test.' + collName } );
db.collectionNames(collName, function(err, names) {
    console.log('Exists: ', names.length > 0);
});
在MongoDB本机驱动程序的2.x版本中,
collectionNames
已被替换为接受筛选器并返回游标的,因此您可以按以下方式执行此操作:

db.listCollections({name: collName})
    .next(function(err, collinfo) {
        if (collinfo) {
            // The collection exists
        }
    });

这个问题涉及本机驱动程序,但我在这里搜索如何在
pymongo
中实现这一点。通常,
pymongo
的api与JS api相同,但在本例中,
collection\u names
没有集合名称的参数(如
johnyhk
),而是第一个参数是布尔值(是否包括系统集合)。由于字符串的计算结果为
True
,因此可能会造成混淆。因此,我希望这能帮助未来的读者:

import pymongo

cl = pymongo.MongoClient()
db = cl['my-db']
if 'my-col' in db.collection_names(False):
   ...
Node.js本机驱动程序中现在有一个方法。它返回当前数据库中所有集合的信息。您可以使用它检查给定集合是否存在:

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

由于MongoDB 3.0,您只需运行:

db.getCollectionNames()
它返回一个数组,其中包含当前数据库中所有集合的名称:

[ "employees", "products", "mylogs"]
选中,或者您也可以使用db.getCollectionFos()。如果您需要有关使用driver和7.6+的每个集合的更多信息,请使用以下命令:

const collections = await db.collections();
if (!collections.map(c => c.s.name).includes(collName)) {
    await db.createCollection(collName);
}
编辑 正如@MattCochrane提到的,
collection.s.name
不再可用;正如@johnyhk和@weekens指出的,正确的方法是使用以下方法:

listCollection()
采用可选过滤器。

如果使用mongodb 3.1.10。 这是检查集合是否存在的方法

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

适用于3.6.*版本的更新答案

/**
*检查mongo数据库中是否存在集合。
* 
*@param db是一个mongo db对象。如。
*client=wait MongoClient.connect(uri);
*db=client.db();
*@param collectionName要搜索的集合的名称
*@returns{Promise}
*/
异步函数doesCollectionExistInDb(db,collectionName){
const collections=await db.collections();
返回集合(
(collection)=>collection.collectionName===collectionName
);
}
...
如果(等待doesCollectionExistInDb(db,‘产品’)){
//执行某些操作,例如创建新集合
}

collection.collectionName
是文档化的集合api的一部分,可以在这里找到:

对于使用mongodb库(V3.6.3)的nodejs,这是我让它工作的唯一方法:

const collectionName = 'products'
const exists = (await (await db.listCollections().toArray()).findIndex((item) => item.name === collectionName) !== -1)
console.log(exists)
希望这能帮助别人

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

}

事实上,这对我很有用

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

});


需要更多信息:您使用的是哪一个连接器库,您检查过它的手册/api文档吗?@Mike'Pomax'Kamermans我使用的是驱动程序库,但在它的api文档中找不到这样的功能。in:
db.collection('system.namespace').find().toArray(函数(err,items){}
晚会迟到了,但是我认为我下面的答案()有一个更直接、更清晰的方法来获取信息。答案中的所有内容都不能在native node.js库中找到。唯一有效的是Nasser提供的内容。到今天为止,这个答案不再有效,`db.listCollections({name:collName}).next(函数(err,collinfo){if(collinfo){//集合存在}});`是如何在nodejs中获取此db对象的有效答案吗?方法
getCollectionNames()
在node.js native lib中不可用。嘿,但我使用的是mongodb lib,它是管理mongo数据库@DanFromGermany的方法,旧API中有,但没有
getCollectionNames()
没有问题。您使用的是哪个版本的MongoDB,这个getCollectionNames()存在于MongoDB 3.0Dude中,mongo的最新节点驱动程序是。3.0甚至不存在。这应该是可接受的答案,因为它是实际处理node.js的唯一答案(如OP要求的)。还有一个liner
db.listCollections({name:colName})。hasNext()
@NikolaLukic在
cb
函数中,第一个参数是错误(
null
,如果没有错误),第二个参数是布尔值,如果存在集合,则为
true
;如果不存在集合,则为
false
collectionExists
函数也可以通过承诺而不是回调来实现。我已经有了与listCollections()相同的信息。toArray。我需要编写简单的函数,比如:isExist(name),并像if(isExist('mycollection')==true){doSomething();}一样使用它。也许我需要异步方法…@NikolaLukic,是的,你可能会得到
if(wait isExist('mycollection'))
if(yield isExist('mycollection'))
。没有其他方法可以使异步方法看起来像同步方法。我猜,
==true
是多余的。刚刚测试了这个节点v8.11.4-mongodb-3.1.10:它工作得很好!您可以使用
some()
而不是
map
includes
将其缩短一点。这在mongodb 3.6.0中不再有效,
name
属性在
collection.s
上不可用。给我一个教训。。我应该比t更清楚