【问题标题】: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 文档中找不到这样的功能。

标签: node.js mongodb node-mongodb-native


【解决方案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) {})
  • 迟到了,但我认为我在下面的回答 (stackoverflow.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 没有集合名称的参数(如JohnnyHKanswer),而是第一个参数是一个布尔值(是否包括系统集合)。由于字符串的计算结果为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
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2018-02-27
              • 2015-12-07
              • 1970-01-01
              • 2015-11-01
              • 2012-06-23
              • 1970-01-01
              • 2013-02-08
              相关资源
              最近更新 更多