node.js - 如何使用Mongoose删除数据库?

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

我找不到用Mongoose放弃它的方法。

Yaron Naveh asked 2019-08-13T20:23:52Z
12个解决方案
156 votes

没有从mongoose中删除集合的方法,你可以做的最好是删除一个集合的内容:

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

但有一种方法可以访问mongodb本机javascript驱动程序,可用于此

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

警告

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

drinchev answered 2019-08-13T20:24:20Z
74 votes

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

您可以删除所有连接的数据库:

var mongoose = require('mongoose');
/* Connect to the DB */
mongoose.connect('mongodb://localhost/mydatabase',function(){
    /* Drop the DB */
    mongoose.connection.db.dropDatabase();
});
hellslam answered 2019-08-13T20:24:51Z
14 votes

如果您像这样修改@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();

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

silverfighter answered 2019-08-13T20:25:29Z
8 votes

试过@hellslam&@ silverfighter的答案。 我发现一个竞争条件让我的测试恢复了。 在我的情况下,我正在运行mocha测试,并且在测试的before函数中我想要擦除整个DB。 这对我有用。

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]

zafrani answered 2019-08-13T20:26:01Z
5 votes

我对其他解决方案的困难在于,如果您想让索引再次运行,他们会依赖重新启动您的应用程序。

根据我的需要(即能够运行单元测试核武所有集合,然后将它们与索引一起重新创建),我最终实现了这个解决方案:

这依赖于underscore.js和async.js库来组装parellel中的索引,如果您反对该库,它可以解开,但我将其留作开发人员的练习器。

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')
    })
  })
})
Eric Caron answered 2019-08-13T20:26:40Z
4 votes

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

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

注意:

  1. 选择引用特定模式的模型(集合模式)你想删除)。
  2. 此操作不会删除集合名称来自数据库。
  3. 这将删除集合中的所有文档。
Danish answered 2019-08-13T20:27:26Z
4 votes

这对Mongoose来说对我有用v4.7.0

mongoose.connection.dropDatabase();
user3344977 answered 2019-08-13T20:27:51Z
4 votes

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

mongoose.connection.dropDatabase();

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

mongoose.connection.db.dropDatabase();

但是,如果在创建数据库连接之后立即运行,则可能会以静默方式失败。 这与连接实际上是异步的,并且在命令发生时尚未设置。 对于像dropDatabase这样的其他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);
    }
}  
Mark Stosberg answered 2019-08-13T20:28:52Z
4 votes

4.6.0+的更新答案,如果您对promises有偏好(请参阅文档):

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

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

从4.11.0开始,不推荐使用Mongoose的默认连接逻辑。 请使用useMongoClient选项选择使用新的连接逻辑,但如果您要升级现有代码库,请确保先测试您的连接!

Andre M answered 2019-08-13T20:29:32Z
1 votes

猫鼬4.6.0+:

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

通过回调连接不再工作:

TypeError:无法读取属性" commandsTakeWriteConcern' 为null

Rayjax answered 2019-08-13T20:30:10Z
0 votes
beforeEach((done) => {
      mongoose.connection.dropCollection('products',(error ,result) => {
      if (error) {
        console.log('Products Collection is not dropped')
      } else {
        console.log(result)
      }
    done()
    })
  })
Revt A answered 2019-08-13T20:30:28Z
-1 votes

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

myMongooseModel.collection.drop();

如测试中所见

Sgnl answered 2019-08-13T20:30:59Z
translate from https://stackoverflow.com:/questions/10081452/how-to-drop-a-database-with-mongoose