Как удалить базу данных с помощью Mongoose?

Я готовлю создание базы данных script в Node.js и Mongoose. Как я могу проверить, существует ли база данных, и если да, удалите (удалите) ее с помощью Mongoose?

Я не мог найти способ бросить его с помощью Mongoose.

Ответ 1

Нет способа удалить коллекцию из mongoose, лучшее, что вы можете сделать, это удалить содержимое одного из них:

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

Но есть способ получить доступ к встроенному javascript файлу mongodb, который можно использовать для этого

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

Предупреждение

Сделайте резервную копию, прежде чем пытаться это сделать, если что-то пойдет не так!

Ответ 2

Mongoose создаст базу данных, если она еще не существует при подключении, поэтому после подключения вы можете просто запросить ее, чтобы увидеть, есть ли что-нибудь в ней.

Вы можете удалить любую базу данных, к которой вы подключены:

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

Ответ 3

Если вы измените решение @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, по крайней мере, это для меня, поэтому я решил поделиться =)

Ответ 4

Попробовали ответы @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

Ответ 5

Трудность, с которой я столкнулся с другими решениями, заключается в том, что они полагаются на перезапуск приложения, если вы хотите, чтобы индексы работали снова.

Для моих нужд (т.е. имея возможность запускать unit test ядерные блоки всех коллекций, затем воссоздает их вместе со своими индексами), я решил реализовать это решение:

Это опирается на библиотеки underscore.js и async.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')
    })
  })
})

Ответ 6

Чтобы удалить конкретную коллекцию в базе данных:

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

Примечание:

  • Выберите модель, относящуюся к конкретной схеме (схема сбора вы хотите удалить).
  • Эта операция не будет удалять имя коллекции из базы данных.
  • Это удаляет все документы в коллекции.

Ответ 7

Это работает для меня, начиная с Mongoose v4.7.0:

mongoose.connection.dropDatabase();

Ответ 8

Лучший способ сбросить базу данных в Mongoose зависит от того, какую версию Mongoose вы используете. Если вы используете версию Mongoose, которая 4.6.4 или новее, то этот метод, добавленный в этом выпуске, скорее всего, будет хорошо работать для вас:

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

Ответ 9

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

myMongooseModel.collection.drop();

как показано в тесты

Ответ 10

Mongoose 4.6.0 +:

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

Передача обратного вызова для подключения больше не будет работать:

TypeError: Не удается прочитать свойства 'commandsTakeWriteConcern' из null

Ответ 11

Обновленный ответ для 4.6.0+, если у вас есть предпочтение promises (см. документы):

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, но сначала проверьте свои подключения, если вы обновляете существующую кодовую базу!