如何检查MongoDB本机nodejs驱动程序中是不是存在集合?

Posted

技术标签:

【中文标题】如何检查MongoDB本机nodejs驱动程序中是不是存在集合?【英文标题】:How to check if a collection exists in Mongodb native nodejs driver?如何检查MongoDB本机nodejs驱动程序中是否存在集合? 【发布时间】:2014-01-28 05:25:16 【问题描述】:

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

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

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

【问题讨论】:

需要更多信息:您使用的是哪个连接器库,您是否查看过它的手册/api 文档? @Mike'Pomax'Kamermans 我正在使用mongo-native 驱动程序库,但我在它的 API 文档中找不到这样的功能。 【参考方案1】:

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

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

虽然在使用默认存储引擎 (MMAPv1) 时查询system.namespaces 仍然有效,但不保证对其他引擎也有效,例如 WiredTiger。

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

可以查询system.namespaces集合:

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

喜欢:

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

返回:

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

当然,什么也没有。

另请参阅:https://github.com/mongodb/specifications/blob/master/source/enumerate-collections.rst

【讨论】:

在mongo-native:db.collection('system.namespaces').find().toArray(function(err, items) ) 迟到了,但我认为我在下面的回答 (***.com/a/40141321/446717) 有一种更直接、更干净的方法来获取该信息 本机 node.js 库中没有答案中的任何内容。 Nasser 提供的唯一有效的东西。 从今天开始,这个答案不再有效,` db.listCollections(name: collName) .next(function(err, collinfo) if (collinfo) // 集合存在 ); ` 是来自this answer 的有效答案 如何在nodejs中获取这个db对象?【参考方案2】:

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

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

在 2.x 版本的 MongoDB 原生驱动程序中,collectionNames 已被替换为 listCollections,它接受过滤器并返回游标,因此您可以这样做:

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

【讨论】:

这应该是公认的答案,因为它是唯一真正处理 node.js 的答案(就像 OP 要求的那样)。 还有一个班轮db.listCollections( name: colName ).hasNext()【参考方案3】:

这个问题是指本机驱动程序,但我在这里搜索如何在pymongo 中执行此操作。通常pymongo 的 api 与 JS api 相同,但在这种情况下,collection_names 没有集合名称的参数(如JohnnyHK 的answer),而是第一个参数是一个布尔值(是否包括系统集合)。由于字符串的计算结果为True,这可能会造成混淆。所以我希望这对未来的读者有所帮助:

import pymongo

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

【讨论】:

【参考方案4】:

Node.js 原生驱动程序中现在有一个listCollections 方法。它返回当前数据库中所有集合的信息。您可以使用它来检查给定的集合是否存在:

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

【讨论】:

@NikolaLukic 在cb 函数中,第一个参数是错误(null 如果没有错误),第二个参数是布尔值,如果集合存在则为true,如果不存在则为falsecollectionExists 函数也可以用 Promise 代替回调来实现。 我已经有了与 listCollections().toArray 相同的信息。我需要编写简单的函数,例如: isExist (name) ,并像 if (isExist('mycollection') == true) doSomething(); 一样使用它 也许我需要异步方法... @NikolaLukic,是的,您最终可能会得到if (await isExist('mycollection'))if (yield isExist('mycollection'))。没有其他方法可以使异步方法看起来像同步方法。我猜,== true 是多余的。【参考方案5】:

从 MongoDB 3.0 开始,您可以简单地运行:

db.getCollectionNames()

返回一个包含当前数据库上所有集合名称的数组:

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

检查Mongo DB Documentation,或者如果您需要有关每个集合的更多信息,也可以使用 db.getCollectionInfos()

【讨论】:

方法getCollectionNames()在node.js原生库中不可用。 嘿,但我是从 mongodb lib 中使用它的,它是管理 mongo 数据库的一个 @DanFromGermany 旧 API 中有 Db.collectionNames() 可用,但根本没有 getCollectionNames() 你使用的是哪个版本的MongoDB,这个getCollectionNames()存在于MongoDB 3.0中 老兄,mongo的最新节点驱动是2.2 (link)。 3.0 甚至都不存在。【参考方案6】:

使用mongo-native驱动和Node.js 7.6+,我使用以下:

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

编辑

正如@MattCochrane 提到的,collection.s.name 不再可用;正如@JohnnyHK 和@weekens 指出的那样,正确的方法是使用listCollections() 方法:

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() 采用可选过滤器。

【讨论】:

刚刚测试了这个 Node v8.11.4 - mongodb - 3.1.10:效果很好! 你可以用some() 代替mapincludes developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 来缩短这个时间 这在 mongodb 3.6.0 中不再有效name 属性在 collection.s 上不可用。对我来说是一个教训。我应该知道不要使用显然不打算成为公共接口的东西。【参考方案7】:

如果你使用 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")  
  ); 
);

【讨论】:

【参考方案8】:

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

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

collection.collectionName 是记录在案的集合 api 的一部分,可在此处找到:http://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html#collectionName

【讨论】:

这在 2021 年对我有用,非常干净的解决方案!【参考方案9】:

对于带有 mongodb 库 (v 3.6.3) 的 nodejs,这是我让它工作的唯一方法:

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

希望对他人有所帮助

【讨论】:

【参考方案10】:
/* 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

【讨论】:

【参考方案11】:

实际上,这对我有用

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

);

【讨论】:

【参考方案12】:

一个异步 TypeScript 函数:

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

【讨论】:

以上是关于如何检查MongoDB本机nodejs驱动程序中是不是存在集合?的主要内容,如果未能解决你的问题,请参考以下文章

通过 NodeJS 与 MongoDB 反应本机 [关闭]

NodeJS 本机驱动程序上的示例 MongoDB 错误是啥样的?

为桌面、移动本机应用程序和 oAuth 功能设计 nodejs expressjs mongodb Webserver 流

使用适用于 Node JS 的 mongodb 本机驱动程序记录所有查询

mongodb本机驱动程序获取没有数据库名称的集合名称

MongoDB NodeJS驱动的browserify兼容性(调试帮助)