如何使用Mongoose删除数据库?


Answers:


166

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

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

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

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

警告

尝试备份之前进行备份,以防万一出问题!


2
当我尝试第二个选项时,我得到“无法读取未定义的属性'collectionName'”
Yaron Naveh 2012年

1
由于所有集合都在哈希表mongoose.connection.collections中,因此您可以简单地列出它们以供使用(mongoose.connection.collections中的集合){mongoose.connection.collections [collection] .drop} ...
有点

3
您有错别字-函数(err)之后的逗号应为:mongoose.connection.collections ['collectionName']。drop(函数(err){console.log('集合删除') ;});
arxpoetica 2012年

3
我是唯一意识到此答案的人并没有解决如何删除数据库的问题。它不要求放弃收集其要求删除数据库..
约瑟夫·范佩西

3
“没有从猫鼬中删除集合的方法”,首先,OP希望删除数据库,而不是排序规则,其次,下面的@hellslam答案很好。
SCBuergel.eth

79

如果连接上尚不存在Mongoose,它将创建一个数据库,因此,一旦建立连接,您就可以查询该数据库以查看其中是否包含任何内容。

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

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

1
我试过了,mongoose.connection.db.dropDatabase()但是发现数据库仍然在那里?我想念什么吗?
Freewind 2012年

如果您以后连接到它,它将被重新创建,尽管为空。删除它后,其中有任何收藏吗?
hellslam

您是在整个使用同一连接还是在创建多个连接?
hellslam 2012年

12
我发现dropDatabase调用应放在connectas 的回调中mongoose.connect('...', function() { ...dropDatabase()})
Freewind 2012年

1
dropDatabase在某些情况下似乎不起作用,但是仍然可以使用直接mongo命令 mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function(err, result) { if (err) { console.log(err); } done(); });
farincz 2014年

14

如果您像这样修改@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至少对我有用,所以我决定分享=)


可以用这个删除db吗?db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);
chovy

2
这很有帮助,谢谢!但是,您的变量名有点误导... mongoose.connect实际上是return mongoose。而不是conn = mongoose.connect(...)我写mongoose.connect(...)然后conn = mongooose.connection
带薪的书呆子

我不认为此代码将始终有效,因为connect是异步的。因此,如果连接没有立即发生,dropDatabase()命令将失败。因此,上述其他解决方案建议将dropDatabase命令放入connect语句或open事件处理程序的回调中。
马克·斯托斯伯格

8

尝试了@hellslam和@silverfighter的答案。我发现比赛条件使我的测试退后。就我而言,我正在运行摩卡测试,而在测试的before函数中,我想擦除整个数据库。这是对我有用的东西。

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


7

如果您对诺言有偏爱(见docs),则为4.6.0+更新的答案:

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

我使用猫鼬4.13.6在自己的代码中测试了此代码。另外,请注意该useMongoClient选项的使用(请参阅docs)。文件显示:

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


5

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

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

这依赖于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')
    })
  })
})

4

要清空数据库中的特定集合,请执行以下操作:

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

注意:

  1. 选择一个参考特定模式的模型(您要删除的集合模式)。
  2. 此操作不会从数据库中删除集合名称。
  3. 这将删除集合中的所有文档。

4

从Mongoose开始,这对我有效v4.7.0

mongoose.connection.dropDatabase();

4

在Mongoose中删除数据库的最佳方法取决于您所使用的Mongoose版本。如果您使用的是4.6.4或更高版本的Mongoose版本,则该版本中添加的此方法很可能对您有效:

mongoose.connection.dropDatabase();

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

mongoose.connection.db.dropDatabase();

但是,如果此操作是在数据库连接创建后立即运行的,则可能会静默失败。这与实际上是异步的并且在命令发生时尚未建立连接有关。对于其他Mongoose调用(例如).find(),通常不会出现问题,它们会一直排队直到打开连接然后再运行。

如果查看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);
    }
}  

2

猫鼬4.6.0+:

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

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

TypeError:无法读取null的属性'commandsTakeWriteConcern'


1
connect返回承诺,因此您可以添加.then((connection) => { ... });到中mongoose.connect。请参阅:mongoosejs.com/docs/connections.html
Andre M,

1
beforeEach((done) => {
      mongoose.connection.dropCollection('products',(error ,result) => {
      if (error) {
        console.log('Products Collection is not dropped')
      } else {
        console.log(result)
      }
    done()
    })
  })

0

由于删除方法在猫鼬库中已弃用,因此我们可以使用deleteMany函数,而无需传递任何参数。

Model.deleteMany();

这将删除该特定模型的所有内容,并且您的收藏集将为空。


0

删除集合中的所有文档:

await mongoose.connection.db.dropDatabase();

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

dropDatabase(): Promise<any>;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.