Cómo soltar una base de datos con Mongoose?

Estoy preparando un script de creación de base de datos en Node.js y Mongoose. ¿Cómo puedo verificar si la base de datos ya existe y, de ser así, soltarla (eliminar) usando Mongoose?

No pude encontrar una manera de dejarlo con Mongoose.

No existe un método para eliminar una colección de mongoose, lo mejor que puede hacer es eliminar el contenido de una:

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

Pero hay una forma de acceder al driver javascript nativo de mongodb, que se puede usar para esto

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

Advertencia

Haz una copia de seguridad antes de intentar esto en caso de que algo salga mal.

Mongoose creará una base de datos si todavía no existe una en la conexión, por lo que una vez que establezcas la conexión, puedes consultarla para ver si hay algo en ella.

Puede soltar cualquier base de datos a la que esté conectado:

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

Si modificas la solución de @hellslam de esta manera, funcionará

Utilizo esta técnica para abandonar la base de datos después de mis pruebas de integración

 //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 al menos lo hizo por mí, así que decidí compartir =)

Intentó las respuestas de @hellslam y @ silverfighter. Encontré una condición de carrera para volver a realizar mis exámenes. En mi caso estoy ejecutando pruebas de moca y en la función anterior de la prueba quiero borrar todo el DB. Esto es lo que funciona para mí.

 var con = mongoose.connect('mongodb://localhost/mydatabase'); mongoose.connection.on('open', function(){ con.connection.db.dropDatabase(function(err, result){ done(); }); }); 

Puedes leer más https://github.com/Automattic/mongoose/issues/1469

La dificultad que he tenido con las otras soluciones es que confían en reiniciar su aplicación si quiere que los índices vuelvan a funcionar.

Para mis necesidades (es decir, poder ejecutar una prueba de unidad de todas las colecciones de armas nucleares, luego las recrea junto con sus índices), terminé implementando esta solución:

Esto depende de las bibliotecas underscore.js y async.js para ensamblar los índices en parellel, podría desenrollarse si estás en contra de esa biblioteca, pero lo dejo como ejercicio para el desarrollador.

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

Para vaciar una colección particular en una base de datos:

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

Nota:

  1. Elija un modelo que se refiera a un esquema particular (esquema de la colección que desea eliminar).
  2. Esta operación no eliminará el nombre de la colección de la base de datos.
  3. Esto borra todos los documentos en una colección.

Esto funciona para mí a partir de Mongoose v4.7.0 :

 mongoose.connection.dropDatabase(); 

La mejor manera de dejar su base de datos en Mongoose depende de la versión de Mongoose que esté usando. Si está utilizando una versión de Mongoose 4.6.4 o posterior, entonces este método agregado en esa versión probablemente funcionará bien para usted:

 mongoose.connection.dropDatabase(); 

En versiones anteriores, este método no existía. En su lugar, debía usar una llamada MongoDB directa:

 mongoose.connection.db.dropDatabase(); 

Sin embargo, si esto se ejecutó justo después de que se creó la conexión de la base de datos, posiblemente podría fallar silenciosamente. Esto está relacionado con que la conexión en realidad sea asíncrona y aún no se haya configurado cuando se produce el comando. Esto normalmente no es un problema para otras llamadas de Mongoose como .find() , que hacen cola hasta que la conexión se abra y luego se ejecute.

Si observa el código fuente para el dropDatabase() directo dropDatabase() que se agregó, puede ver que fue diseñado para resolver este problema exacto. Verifica si la conexión está abierta y lista. Si es así, dispara el comando inmediatamente. De lo contrario, registra el comando para ejecutar cuando se abre la conexión de la base de datos.

Algunas de las sugerencias anteriores recomiendan siempre colocar su comando dropDatabase en el controlador open . Pero eso solo funciona en el caso cuando la conexión aún no está abierta.

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

Aquí hay una versión simple de la lógica anterior que se puede usar con las versiones anteriores de 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); } } 

Una respuesta actualizada, para 4.6.0+, si tiene preferencia por las promesas ( ver documentos ):

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

Probé este código en mi propio código, usando mongoose 4.13.6. Además, tenga en cuenta el uso de la opción useMongoClient ( ver documentos ). Los documentos indican:

La lógica de conexión predeterminada de Mongoose está obsoleta desde 4.11.0. Opte por la nueva lógica de conexión utilizando la opción useMongoClient, ¡pero asegúrese de probar sus conexiones primero si está actualizando una base de código existente!

Mangosta 4.6.0+:

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

Pasar una callback para conectarse ya no funcionará:

TypeError: no se puede leer la propiedad ‘commandsTakeWriteConcern’ de null

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

Para eliminar todos los documentos en una colección:

 myMongooseModel.collection.drop(); 

como se ve en las pruebas