【问题标题】:How to drop a database with Mongoose?如何使用 Mongoose 删除数据库?
【发布时间】:2012-04-22 07:30:13
【问题描述】:

我正在用 Node.js 和 Mongoose 准备一个数据库创建脚本。 如何检查数据库是否已经存在,如果存在,使用 Mongoose 删除(删除)它?

我找不到用 Mongoose 删除它的方法。

【问题讨论】:

标签: node.js mongodb mongoose


【解决方案1】:

没有办法从猫鼬中删除一个集合,你能做的最好的就是删除一个集合的内容:

Model.remove({}, function(err) { 
   console.log('collection removed') 
});

但是有一种方法可以访问mongodb原生的javascript驱动,可以用这个

mongoose.connection.collections['collectionName'].drop( function(err) {
    console.log('collection dropped');
});

警告

在尝试此之前进行备份,以防出现任何问题!

【讨论】:

  • 当我尝试第二个选项时,我得到“无法读取未定义的属性 'collectionName'”
  • 由于所有集合都在哈希 mongoose.connection.collections 中,您可以简单地列出它们(在 mongoose.connection.collections 中的集合){ mongoose.connection.collections[collection].drop } .. .smth类似
  • 你打错了——function(err) 后面的一个额外的逗号应该是: mongoose.connection.collections['collectionName'].drop( function(err) { console .log('收集被丢弃'); });
  • 只有我一个人意识到这个答案没有解决如何删除数据库的问题。它不要求删除一个集合它要求删除一个数据库..
  • “没有办法从猫鼬中删除一个集合”,首先OP想要删除一个数据库,而不是一个colledtion,其次@hellslam下面的答案效果很好。
【解决方案2】:

如果连接时尚不存在数据库,Mongoose 将创建一个数据库,因此一旦建立连接,您只需查询它以查看其中是否有任何内容。

您可以删除您连接到的任何数据库:

var mongoose = require('mongoose');
/* Connect to the DB */
mongoose.connect('mongodb://localhost/mydatabase',function(){
    /* Drop the DB */
    mongoose.connection.db.dropDatabase();
});

【讨论】:

  • 我试过mongoose.connection.db.dropDatabase() 但我发现数据库还在?我错过了什么吗?
  • 如果您之后连接到它,它将被重新创建,尽管它是空的。丢了之后里面有收藏吗?
  • 您是始终使用同一个连接,还是创建多个连接?
  • 我发现dropDatabase调用应该放在connect的回调中,如mongoose.connect('...', function() { ...dropDatabase()})
  • dropDatabase在某些情况下似乎不起作用,但直接mongo命令仍然可以使用mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function(err, result) { if (err) { console.log(err); } done(); });
【解决方案3】:

如果你像这样修改@hellslam 的解决方案,那么它会起作用

我在集成测试后使用这种技术删除数据库

//CoffeeScript
mongoose = require "mongoose"
conn = mongoose.connect("mongodb://localhost/mydb")

conn.connection.db.dropDatabase()

//JavaScript
var conn, mongoose;
mongoose = require("mongoose");
conn = mongoose.connect("mongodb://localhost/mydb");

conn.connection.db.dropDatabase();

至少它对我有用,所以我决定分享 =)

【讨论】:

  • 可以用这个删除 db 吗? db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);
  • 这很有帮助,谢谢!但是,您的变量名称有点误导...mongoose.connect 实际上返回mongoose。而不是conn = mongoose.connect(...),我会写mongoose.connect(...)然后conn = mongooose.connection
  • 我认为这段代码不会一直有效,因为connect 是异步的。因此,如果连接没有立即发生,则 dropDatabase() 命令将失败。这就是为什么上面的其他解决方案建议将dropDatabase 命令放在connect 语句或open 事件处理程序的回调中。
【解决方案4】:

尝试了@hellslam 和@silverfighter 的答案。我发现一个比赛条件阻碍了我的测试。就我而言,我正在运行 mocha 测试,并且在测试的前功能中我想擦除整个数据库。这对我有用。

var con = mongoose.connect('mongodb://localhost/mydatabase');
mongoose.connection.on('open', function(){
    con.connection.db.dropDatabase(function(err, result){
        done();
    });
});

您可以阅读更多https://github.com/Automattic/mongoose/issues/1469

【讨论】:

    【解决方案5】:

    4.6.0+ 的更新答案,如果您偏好 Promise (see docs):

    mongoose.connect('mongodb://localhost/mydb', { useMongoClient: true })
    .then((connection) => {
       connection.db.dropDatabase();
       // alternatively:
       // mongoose.connection.db.dropDatabase();
    });
    

    我使用 mongoose 4.13.6 在自己的代码中测试了这段代码。另外,请注意useMongoClient 选项(see docs)的使用。文档表明:

    Mongoose 的默认连接逻辑自 4.11.0 起已弃用。请使用 useMongoClient 选项选择新的连接逻辑,但如果您要升级现有代码库,请确保首先测试您的连接!

    【讨论】:

      【解决方案6】:

      我在使用其他解决方案时遇到的困难是,如果您想让索引再次工作,它们依赖于重新启动您的应用程序。

      出于我的需要(即能够对所有集合进行单元测试,然后重新创建它们及其索引),我最终实现了这个解决方案:

      这依赖于 underscore.jsasync.js 库以并行方式组装索引,如果您反对该库,它可能会被取消,但我将其作为开发人员的练习器。

      mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function(err, result) {
        var mongoPath = mongoose.connections[0].host + ':' + mongoose.connections[0].port + '/' + mongoose.connections[0].name
        //Kill the current connection, then re-establish it
        mongoose.connection.close()
        mongoose.connect('mongodb://' + mongoPath, function(err){
          var asyncFunctions = []
      
          //Loop through all the known schemas, and execute an ensureIndex to make sure we're clean
          _.each(mongoose.connections[0].base.modelSchemas, function(schema, key) {
            asyncFunctions.push(function(cb){
              mongoose.model(key, schema).ensureIndexes(function(){
                return cb()
              })
            })
          })
      
          async.parallel(asyncFunctions, function(err) {
            console.log('Done dumping all collections and recreating indexes')
          })
        })
      })
      

      【讨论】:

        【解决方案7】:

        这对我来说适用于 Mongoose v4.7.0:

        mongoose.connection.dropDatabase();
        

        【讨论】:

          【解决方案8】:

          清空数据库中的特定集合:

          model.remove(function(err, p){
              if(err){ 
                  throw err;
              } else{
                  console.log('No Of Documents deleted:' + p);
              }
          });
          

          注意:

          1. 选择引用特定模式的模型(集合模式 你想删除)。
          2. 此操作不会删除集合名称 来自数据库。
          3. 这将删除集合中的所有文档。

          【讨论】:

            【解决方案9】:

            在 Mongoose 中删除数据库的最佳方法取决于您使用的 Mongoose 版本。如果您使用的是 4.6.4 或更高版本的 Mongoose,那么在该版本中添加的这个方法很可能适合您:

            mongoose.connection.dropDatabase();
            

            在旧版本中,此方法不存在。相反,您将使用直接 MongoDB 调用:

            mongoose.connection.db.dropDatabase();
            

            但是,如果它是在数据库连接创建之后运行的,它可能会静默失败。这与连接实际上是异步的并且在命令发生时尚未建立有关。对于像 .find() 这样的其他 Mongoose 调用,这通常不是问题,它们会排队等待连接打开然后运行。

            如果您查看添加的dropDatabase() 快​​捷方式的源代码,您会发现它旨在解决这个确切的问题。它检查连接是否打开并准备好。如果是这样,它会立即触发命令。如果没有,它会在数据库连接打开时注册要运行的命令。

            上面的一些建议建议始终将您的dropDatabase 命令放在open 处理程序中。但这仅适用于连接尚未打开的情况。

            Connection.prototype.dropDatabase = function(callback) {
              var Promise = PromiseProvider.get();
              var _this = this;
              var promise = new Promise.ES6(function(resolve, reject) {
                if (_this.readyState !== STATES.connected) {
                  _this.on('open', function() {
                    _this.db.dropDatabase(function(error) {
                      if (error) {
                        reject(error);
                      } else {
                        resolve();
                      }
                    });
                  });
                } else {
                  _this.db.dropDatabase(function(error) {
                    if (error) {
                      reject(error);
                    } else {
                      resolve();
                    }
                  });
                }
              });
              if (callback) {
                promise.then(function() { callback(); }, callback);
              }
              return promise;
            };
            

            这是上述逻辑的一个简单版本,可用于早期 Mongoose 版本:

            // This shim is backported from Mongoose 4.6.4 to reliably drop a database
            // http://stackoverflow.com/a/42860208/254318
            // The first arg should be "mongoose.connection"
            function dropDatabase (connection, callback) {
                // readyState 1 === 'connected'
                if (connection.readyState !== 1) {
                  connection.on('open', function() {
                    connection.db.dropDatabase(callback);
                  });
                } else {
                  connection.db.dropDatabase(callback);
                }
            }  
            

            【讨论】:

              【解决方案10】:

              猫鼬 4.6.0+:

              mongoose.connect('mongodb://localhost/mydb')
              mongoose.connection.once('connected', () => {
                  mongoose.connection.db.dropDatabase();
              });
              

              将回调传递给连接将不再起作用:

              TypeError:无法读取 null 的属性“commandsTakeWriteConcern”

              【讨论】:

              【解决方案11】:

              2020 年更新

              创建一个名为 drop.js 的新文件,即 并放入里面

              require('dotenv').config()
              const url = process.env.ATLAS_URI;
              mongoose.connect(url, {
                useNewUrlParser: true,
                useCreateIndex: true,
                useUnifiedTopology: true,
                useFindAndModify: false
              });
              
              const connection = mongoose.connection;
              connection.once('open', () => {
                console.log("MongoDB database connection established successfully");
              })
              
              
              mongoose.connection.dropDatabase().then(
                async() => {
                 
                  try {
                    mongoose.connection.close()
                   
                  }
                  catch (err) {
                    console.log(err)
                  }
              
               }
                
              );
              

              在你的 package.json 中

              in your package.json 
               "scripts": {
                  
                  "drop": "node models/drop.js",
                 
                }
              

              在您的控制台上运行它并

              【讨论】:

              • 如果你只写 mongoose.connection.dropDatabase 你会被卡住并且你 conc 仍然是打开的所以如果你想关闭它你应该处理你从它那里得到的承诺 try and catch to远离这个错误未处理的承诺拒绝已被弃用。将来,未处理的 Promise 拒绝将使用非零退出代码终止 Node.js 进程。
              【解决方案12】:
              beforeEach((done) => {
                    mongoose.connection.dropCollection('products',(error ,result) => {
                    if (error) {
                      console.log('Products Collection is not dropped')
                    } else {
                      console.log(result)
                    }
                  done()
                  })
                })
              

              【讨论】:

                【解决方案13】:

                要删除集合中的所有文档:

                await mongoose.connection.db.dropDatabase();
                

                此答案基于 mongoose index.d.ts 文件:

                dropDatabase(): Promise<any>;
                

                【讨论】:

                  【解决方案14】:
                  mongoose.connect(`mongodb://localhost/${dbname}`, {
                          useNewUrlParser: true,
                          useCreateIndex: true,
                          useFindAndModify: true,
                          useUnifiedTopology: true
                      })
                          .then((connection) => {
                              mongoose.connection.db.dropDatabase();
                          });
                  

                  要删除一个完整的数据库,只需传递名称... 这个在 4.4 版上运行良好

                  【讨论】:

                    【解决方案15】:

                    由于 mongoose 库中的 remove 方法已被弃用,我们可以使用不传递参数的 deleteMany 函数。

                    Model.deleteMany();
                    

                    这将删除此特定模型的所有内容,您的收藏将是空的。

                    【讨论】:

                      【解决方案16】:

                      删除集合中的所有文档:

                      myMongooseModel.collection.drop();
                      

                      tests中所见

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 2021-05-15
                        • 2016-07-02
                        • 2016-03-30
                        • 2017-05-07
                        • 1970-01-01
                        • 2011-08-14
                        相关资源
                        最近更新 更多