113

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

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

4

16 回答 16

177

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

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

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

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

警告

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

于 2012-04-10T12:01:32.837 回答
95

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

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

var mongoose = require('mongoose');
/* Connect to the DB */
mongoose.connect('mongodb://localhost/mydatabase',function(){
    /* Drop the DB */
    mongoose.connection.db.dropDatabase();
});
于 2012-04-29T02:25:06.163 回答
16

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

于 2012-06-04T14:35:15.450 回答
9

尝试了@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

于 2015-07-12T21:27:37.850 回答
7

如果您偏爱 Promise,则为 4.6.0+ 提供更新的答案(请参阅文档):

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

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

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

于 2017-12-12T18:46:10.120 回答
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')
    })
  })
})
于 2013-03-27T19:26:29.037 回答
5

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

mongoose.connection.dropDatabase();
于 2016-11-30T00:17:26.757 回答
4

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

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

笔记:

  1. 选择一个引用特定模式的模型(您希望删除的集合模式)。
  2. 此操作不会从数据库中删除集合名称。
  3. 这将删除集合中的所有文档。
于 2013-07-03T12:48:51.540 回答
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);
    }
}  
于 2017-03-17T14:33:34.130 回答
3

猫鼬 4.6.0+:

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

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

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

于 2017-08-07T09:54:27.607 回答
3

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",
   
  }

在您的控制台上运行它并

于 2020-12-10T06:36:25.987 回答
1
beforeEach((done) => {
      mongoose.connection.dropCollection('products',(error ,result) => {
      if (error) {
        console.log('Products Collection is not dropped')
      } else {
        console.log(result)
      }
    done()
    })
  })
于 2018-07-01T09:04:03.427 回答
1

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

await mongoose.connection.db.dropDatabase();

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

dropDatabase(): Promise<any>;
于 2020-06-07T16:37:42.647 回答
1
mongoose.connect(`mongodb://localhost/${dbname}`, {
        useNewUrlParser: true,
        useCreateIndex: true,
        useFindAndModify: true,
        useUnifiedTopology: true
    })
        .then((connection) => {
            mongoose.connection.db.dropDatabase();
        });

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

于 2020-11-06T10:09:25.750 回答
0

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

Model.deleteMany();

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

于 2020-04-30T09:06:07.253 回答
-2

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

myMongooseModel.collection.drop();

测试所示

于 2017-04-06T00:09:43.413 回答