如何删除一个数据库与猫鼬?

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

我找不到办法和猫鼬撇清关系。

121784 次浏览

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

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

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

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

警告

在尝试之前做一个备份,以防万一出现问题!

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

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

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

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

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

//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();

至少对我来说是这样,所以我决定分享

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

For my needs (i.e. being able to run a unit test the nukes all collections, then recreates them along with their indexes), I ended up implementing this solution:

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

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

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

注:

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

尝试了“地狱摔跤”和“银翼战士”的回答。我发现一个比赛条件阻碍了我的测试。在我的例子中,我正在运行 mocha 测试,在 test 的 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

这对我来说是有效的,作为猫鼬 v4.7.0:

mongoose.connection.dropDatabase();

在 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);
}
}

用于删除集合中的所有文档:

myMongooseModel.collection.drop();

就像在 tests中看到的那样

猫鼬4.6.0 + :

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

传递一个连接回调将不再有效:

TypeError: 无法读取 null 的 commandsTakeWriteConcern 属性

对于4.6.0 + ,如果你偏爱承诺(看医生) ,更新后的答案是:

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

我用自己的代码测试了这个代码,用的是猫鼬4.13.6。另外,请注意 useMongoClient选项(看医生)的使用。文件显示:

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

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

由于删除方法在猫鼬库中是折旧的,所以我们可以在不传递任何参数的情况下使用 delete temany 函数。

Model.deleteMany();

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

删除集合中的所有文档:

await mongoose.connection.db.dropDatabase();

This answer is based off the mongoose index.d.ts file:

dropDatabase(): Promise<any>;
mongoose.connect(`mongodb://localhost/${dbname}`, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: true,
useUnifiedTopology: true
})
.then((connection) => {
mongoose.connection.db.dropDatabase();
});

要删除完整的数据库,只需传递名称..。 这个版本在4.4版本中工作得非常好

2020年最新情况

创建一个名为 drop.js 的新文件 and put inside

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)
}


}
  

);

在你的包里 Json

in your package.json
"scripts": {
    

"drop": "node models/drop.js",
   

}

在你的控制台上运行它