Как удалить базу данных с помощью Mongoose?
Я готовлю сценарий создания базы данных в узле.JS и мангусты. Как я могу проверить, существует ли база данных, и если да, то удалить (удалить) ее с помощью Мангуста?
Я не мог найти способ, чтобы удалить его с Мангустом.
12 ответов
нет метода для удаления коллекцию из Мангуста, лучшее, что вы можете сделать, это удалить содержимое одного :
Model.remove({}, function(err) {
console.log('collection removed')
});
но есть способ получить доступ к родному драйверу javascript mongodb, который можно использовать для этого
mongoose.connection.collections['collectionName'].drop( function(err) {
console.log('collection dropped');
});
предупреждение
сделайте резервную копию, прежде чем пытаться это в случае, если что-то пойдет не так!
Мангуст создаст базу данных, если она еще не существует при подключении, поэтому, как только вы сделаете соединение, вы можете просто запросить ее, чтобы увидеть, есть ли что-нибудь в ней.
вы можете удалить любую базу данных, к которой вы подключены:
var mongoose = require('mongoose');
/* Connect to the DB */
mongoose.connect('mongodb://localhost/mydatabase',function(){
/* Drop the DB */
mongoose.connection.db.dropDatabase();
});
Если вы измените решение @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 по крайней мере, это сделал для меня, поэтому я решил поделиться =)
попробовал ответы @hellslam и @silverfighter. Я обнаружил, что состояние гонки сдерживает мои тесты. В моем случае я запускаю тесты mocha, и в функции 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
сложность с другими решениями заключается в том, что они полагаются на перезапуск вашего приложения, если вы хотите, чтобы индексы снова работали.
для моих нужд (т. е. будучи в состоянии запустить модульный тест nukes все коллекции, а затем воссоздает их вместе с их индексами), я закончил реализацию этого решения:
это зависит от подчеркивания.js и асинхронность.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')
})
})
})
чтобы очистить определенную коллекцию в базе данных:
model.remove(function(err, p){
if(err){
throw err;
} else{
console.log('No Of Documents deleted:' + p);
}
});
Примечание:
- выберите модель, ссылающуюся на определенную схему (схему коллекции вы хотите удалить).
- эта операция не удалит имя коллекции из базы данных.
- удаляет все документы в коллекции.
лучший способ удалить базу данных в Мангусте зависит от того, какую версию Мангуста вы используете. Если вы используете версию Мангуста, что 4.6.4 или новее, то этот метод, добавленный в этом выпуске, вероятно, будет работать хорошо для вас:
mongoose.connection.dropDatabase();
в более старых выпусках этот метод не существовал. Вместо этого вы должны были использовать прямой вызов MongoDB:
mongoose.connection.db.dropDatabase();
однако, если это было запущено сразу после создания подключения к базе данных, это может произойти беззвучно. Это связано с тем, что соединение фактически асинхронно и еще не настроено, когда происходит команда. Обычно это не проблема для других вызовов Мангуста, таких как .find()
, которая очередь, пока соединение не будет открыто, а затем запустить.
если вы посмотрите на исходный код 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;
};
вот простая версия приведенной выше логики, которая может быть использована с более ранними версиями Мангуста:
// 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+, если у вас есть предпочтение для обещаний (см. docs):
mongoose.connect('mongodb://localhost/mydb', { useMongoClient: true })
.then((connection) => {
connection.db.dropDatabase();
// alternatively:
// mongoose.connection.db.dropDatabase();
});
Я тестировал этот код в своем собственном коде, используя mongoose 4.13.6. Кроме того, обратите внимание на использование (см. docs). Документы указывают:
логика подключения мангуста по умолчанию устарела с 4.11.0. Пожалуйста, войдите в новую логику подключения, используя опцию useMongoClient, но убедитесь, что вы сначала проверяете свои соединения, если вы обновляете существующую кодовую базу!
Мангуст 4.6.0+:
mongoose.connect('mongodb://localhost/mydb')
mongoose.connection.once('connected', () => {
mongoose.connection.db.dropDatabase();
});
передача обратного вызова для подключения больше не будет работать:
TypeError: не удается прочитать свойство "commandsTakeWriteConcern" null
beforeEach((done) => {
mongoose.connection.dropCollection('products',(error ,result) => {
if (error) {
console.log('Products Collection is not dropped')
} else {
console.log(result)
}
done()
})
})