我正在用Node.js和Mongoose准备数据库创建脚本。如何检查数据库是否已经存在,如果存在,请使用Mongoose删除(删除)该数据库?
我找不到用Mongoose删除它的方法。
我正在用Node.js和Mongoose准备数据库创建脚本。如何检查数据库是否已经存在,如果存在,请使用Mongoose删除(删除)该数据库?
我找不到用Mongoose删除它的方法。
Answers:
没有办法从猫鼬中删除一个集合,最好的办法是删除其中一个的内容:
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();
});
mongoose.connection.db.dropDatabase()
但是发现数据库仍然在那里?我想念什么吗?
dropDatabase
调用应放在connect
as 的回调中mongoose.connect('...', function() { ...dropDatabase()})
。
mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function(err, result) { if (err) { console.log(err); } done(); });
如果您像这样修改@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 = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);
mongoose.connect
实际上是return mongoose
。而不是conn = mongoose.connect(...)
我写mongoose.connect(...)
然后conn = mongooose.connection
。
connect
是异步的。因此,如果连接没有立即发生,dropDatabase()命令将失败。因此,上述其他解决方案建议将dropDatabase
命令放入connect
语句或open
事件处理程序的回调中。
尝试了@hellslam和@silverfighter的答案。我发现比赛条件使我的测试退后。就我而言,我正在运行摩卡测试,而在测试的before函数中,我想擦除整个数据库。这是对我有用的东西。
var con = mongoose.connect('mongodb://localhost/mydatabase');
mongoose.connection.on('open', function(){
con.connection.db.dropDatabase(function(err, result){
done();
});
});
如果您对诺言有偏爱(见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选项选择加入新的连接逻辑,但是如果要升级现有代码库,请确保先测试连接!
我在使用其他解决方案时遇到的困难是,如果您要使索引重新工作,它们将依赖于重新启动应用程序。
为了我的需要(即能够对所有集合进行单元测试,然后重新创建它们以及它们的索引),我最终实现了此解决方案:
这依赖于underscore.js和async.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')
})
})
})
在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);
}
}
猫鼬4.6.0+:
mongoose.connect('mongodb://localhost/mydb')
mongoose.connection.once('connected', () => {
mongoose.connection.db.dropDatabase();
});
传递回调连接将不再起作用:
TypeError:无法读取null的属性'commandsTakeWriteConcern'
connect
返回承诺,因此您可以添加.then((connection) => { ... });
到中mongoose.connect
。请参阅:mongoosejs.com/docs/connections.html