it-swarm.com.de

Wie lösche ich eine Datenbank mit Mongoose?

Ich bereite ein Datenbankerstellungsskript in Node.js und Mongoose vor. Wie kann ich überprüfen, ob die Datenbank bereits vorhanden ist, und wenn ja, löschen Sie sie mit Mongoose?

Ich konnte keinen Weg finden, es mit Mongoose fallen zu lassen.

87
Yaron Naveh

Es gibt keine Methode zum Löschen einer Sammlung aus dem Mungo. Am besten entfernen Sie den Inhalt eines Mungos:

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

Es gibt jedoch eine Möglichkeit, auf den mongodb-eigenen Javascript-Treiber zuzugreifen, der hierfür verwendet werden kann

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

Warnung

Machen Sie eine Sicherungskopie, bevor Sie dies versuchen, falls etwas schief geht!

152
drinchev

Mongoose erstellt eine Datenbank, wenn noch keine Verbindung besteht. Wenn Sie die Verbindung hergestellt haben, können Sie sie einfach abfragen, um zu sehen, ob etwas vorhanden ist.

Sie können jede Datenbank löschen, mit der Sie verbunden sind:

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

Wenn Sie die Lösung von @ hellslam auf diese Weise ändern, wird sie funktionieren

Ich verwende diese Technik, um die Datenbank nach meinen Integrationstests zu löschen

//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 zumindest hat es für mich getan, also entschied ich mich zu teilen =)

14
silverfighter

Versuchte die Antworten von @ hellslam und @ silverfighter. Ich fand eine Rennbedingung, die meine Tests zurückhielt. In meinem Fall führe ich Mokka-Tests aus und in der Funktion vor dem Test möchte ich die gesamte Datenbank löschen. Folgendes funktioniert für mich.

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

Lesen Sie mehr https://github.com/Automattic/mongoose/issues/1469

8
zafrani

Die Schwierigkeit, die ich mit den anderen Lösungen hatte, besteht darin, dass sie Ihre Anwendung neu starten müssen, wenn die Indizes wieder funktionieren sollen.

Für meine Bedürfnisse (d. H. In der Lage zu sein, einen Unit-Test der Atomwaffensammlung durchzuführen und sie dann zusammen mit ihren Indizes neu zu erstellen, habe ich diese Lösung implementiert:

Dies hängt von den Bibliotheken underscore.js und async.js ab, um die Indizes in Parellel zusammenzustellen. Es könnte abgewickelt werden, wenn Sie gegen diese Bibliothek sind, aber ich lasse das dem Entwickler als Übungsgerät .

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')
    })
  })
})
5
Eric Caron

So leeren Sie eine bestimmte Sammlung in einer Datenbank:

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

Hinweis: 

  1. Wählen Sie ein Modell aus, das sich auf ein bestimmtes Schema bezieht (Schema der Sammlung. Sie möchten löschen). 
  2. Durch diesen Vorgang wird der Sammlungsname Nicht aus der Datenbank gelöscht.
  3. Dadurch werden alle Dokumente in einer Sammlung gelöscht.
4
Danish

Das funktioniert für mich ab Mongoose v4.7.0:

mongoose.connection.dropDatabase();
4
user3344977

Die beste Methode zum Löschen Ihrer Datenbank in Mongoose hängt davon ab, welche Mongoose-Version Sie verwenden. Wenn Sie eine Mongoose-Version der Version 4.6.4 oder neuer verwenden, wird diese in dieser Version hinzugefügte Methode wahrscheinlich für Sie funktionieren:

mongoose.connection.dropDatabase();

In älteren Versionen gab es diese Methode nicht. Stattdessen sollten Sie einen direkten MongoDB-Aufruf verwenden:

mongoose.connection.db.dropDatabase();

Wenn dies jedoch unmittelbar nach dem Erstellen der Datenbankverbindung ausgeführt wurde, kann dies möglicherweise unbemerkt fehlschlagen. Dies hängt damit zusammen, dass die Verbindung tatsächlich asynchron ist und noch nicht eingerichtet ist, wenn der Befehl ausgeführt wird. Dies ist normalerweise kein Problem für andere Mongoose-Aufrufe wie .find(), die sich in der Warteschlange befinden, bis die Verbindung geöffnet ist und dann ausgeführt wird.

Wenn Sie sich den Quellcode für die hinzugefügte dropDatabase()-Verknüpfung ansehen, können Sie sehen, dass er genau dieses Problem lösen sollte. Es wird geprüft, ob die Verbindung geöffnet und bereit ist. Wenn ja, wird der Befehl sofort ausgelöst. Wenn nicht, wird der Befehl registriert, der ausgeführt werden soll, wenn die Datenbankverbindung geöffnet wurde.

In einigen der oben genannten Vorschläge wird empfohlen, always Ihren dropDatabase-Befehl in den open-Handler zu setzen. Das funktioniert aber nur, wenn die Verbindung noch nicht geöffnet ist. 

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

Hier ist eine einfache Version der obigen Logik, die mit früheren Mongoose-Versionen verwendet werden kann:

// 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);
    }
}  
3
Mark Stosberg

Eine aktualisierte Antwort für 4.6.0+, wenn Sie Versprechen bevorzugen ( siehe docs ):

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

Ich habe diesen Code in meinem eigenen Code mit mongoose 4.13.6 getestet. Beachten Sie auch die Verwendung der Option useMongoClient ( siehe docs ). Dokumente zeigen an: 

Die Standardverbindungslogik von Mongoose ist seit 4.11.0 veraltet. Bitte melden Sie sich mit der Option useMongoClient für die neue Verbindungslogik an. Testen Sie jedoch zuerst Ihre Verbindungen, wenn Sie eine vorhandene Codebase aktualisieren.

3
Andre M

Mungo 4.6.0+:

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

Das Übergeben eines Rückrufs an die Verbindung funktioniert nicht mehr:

TypeError: Eigenschaft 'commandTakeWriteConcern' von null kann nicht gelesen werden

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