Как удалить базу данных с помощью 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);
    }
});

Примечание:

  1. выберите модель, ссылающуюся на определенную схему (схему коллекции вы хотите удалить).
  2. эта операция не удалит имя коллекции из базы данных.
  3. удаляет все документы в коллекции.

это работает для меня, как мангусты v4.7.0:

mongoose.connection.dropDatabase();

лучший способ удалить базу данных в Мангусте зависит от того, какую версию Мангуста вы используете. Если вы используете версию Мангуста, что 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()
    })
  })

для удаления всех документов в коллекции:

myMongooseModel.collection.drop();

Как видно тесты