Ich bereite ein Datenbankerstellungsskript in Node.js und Mongoose vor. Wie kann ich überprüfen, ob die Datenbank bereits vorhanden ist, und wenn ja, sie mit Mongoose löschen (löschen)?
Ich konnte keinen Weg finden, es mit Mungo fallen zu lassen.
Ich bereite ein Datenbankerstellungsskript in Node.js und Mongoose vor. Wie kann ich überprüfen, ob die Datenbank bereits vorhanden ist, und wenn ja, sie mit Mongoose löschen (löschen)?
Ich konnte keinen Weg finden, es mit Mungo fallen zu lassen.
Antworten:
Es gibt keine Methode, um eine Sammlung von Mungos zu löschen. Das Beste, was Sie tun können, ist, den Inhalt einer Sammlung zu entfernen:
Model.remove({}, function(err) {
console.log('collection removed')
});
Es gibt jedoch eine Möglichkeit, auf den mongodb nativen Javascript-Treiber zuzugreifen, der dafür verwendet werden kann
mongoose.connection.collections['collectionName'].drop( function(err) {
console.log('collection dropped');
});
Erstellen Sie ein Backup, bevor Sie dies versuchen, falls etwas schief geht!
Mongoose erstellt eine Datenbank, falls in der Verbindung noch keine vorhanden ist. Sobald Sie die Verbindung hergestellt haben, können Sie sie einfach abfragen, um festzustellen, ob sich etwas darin befindet.
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();
});
mongoose.connection.db.dropDatabase()
aber ich habe festgestellt, dass die Datenbank noch vorhanden ist. Vermisse ich etwas
dropDatabase
Aufruf in den Rückruf von connect
, as gesetzt werden sollte mongoose.connect('...', function() { ...dropDatabase()})
.
mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function(err, result) { if (err) { console.log(err); } done(); });
Wenn Sie die Lösung von @ hellslam wie folgt ändern, funktioniert sie
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 hat es zumindest für mich getan, also habe ich beschlossen zu teilen =)
db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);
mongoose.connect
kehren tatsächlich zurück mongoose
. Anstatt conn = mongoose.connect(...)
würde ich schreiben mongoose.connect(...)
und dann conn = mongooose.connection
.
connect
asynchron ist. Wenn die Verbindung nicht sofort hergestellt wird, schlägt der Befehl dropDatabase () fehl. Aus diesem Grund wurde in den anderen oben genannten Lösungen empfohlen, den dropDatabase
Befehl in den Rückruf der connect
Anweisung oder eines open
Ereignishandlers einzufügen.
Versuchte die Antworten von @ hellslam und @ silverfighter. Ich fand eine Rennbedingung, die meine Tests zurückhielt. In meinem Fall führe ich Mokka-Tests durch und in der Vorher-Funktion des Tests möchte ich die gesamte Datenbank löschen. Folgendes funktioniert bei mir.
var con = mongoose.connect('mongodb://localhost/mydatabase');
mongoose.connection.on('open', function(){
con.connection.db.dropDatabase(function(err, result){
done();
});
});
Sie können mehr unter https://github.com/Automattic/mongoose/issues/1469 lesen
Eine aktualisierte Antwort für 4.6.0+, wenn Sie Versprechen bevorzugen ( siehe Dokumente ):
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 Mungo 4.13.6 getestet. Beachten Sie auch die Verwendung der useMongoClient
Option ( siehe Dokumente ). Dokumente zeigen an:
Die Standardverbindungslogik von Mongoose ist ab 4.11.0 veraltet. Bitte aktivieren Sie die neue Verbindungslogik mit der Option useMongoClient. Testen Sie jedoch zuerst Ihre Verbindungen, wenn Sie eine vorhandene Codebasis aktualisieren!
Die Schwierigkeit, die ich mit den anderen Lösungen hatte, besteht darin, dass sie darauf angewiesen sind, Ihre Anwendung neu zu starten, wenn Sie möchten, dass die Indizes wieder funktionieren.
Für meine Anforderungen (dh in der Lage zu sein, einen Unit-Test der Atomwaffen aller Sammlungen 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 parallel zusammenzustellen. Es könnte abgewickelt werden, wenn Sie gegen diese Bibliothek sind, aber ich überlasse dies 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')
})
})
})
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:
Dies funktioniert bei mir ab Mungo v4.7.0
:
mongoose.connection.dropDatabase();
Der beste Weg, Ihre Datenbank in Mongoose zu löschen, hängt davon ab, welche Version von Mongoose Sie verwenden. Wenn Sie eine Version von Mongoose verwenden, die 4.6.4 oder höher ist, funktioniert diese in dieser Version hinzugefügte Methode wahrscheinlich einwandfrei für Sie:
mongoose.connection.dropDatabase();
In älteren Versionen existierte 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 es möglicherweise unbemerkt fehlschlagen. Dies hängt damit zusammen, dass die Verbindung tatsächlich asynchron ist und noch nicht eingerichtet wird, wenn der Befehl ausgeführt wird. Dies ist normalerweise kein Problem für andere Mongoose-Anrufe 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 dropDatabase()
hinzugefügte Verknüpfung , können Sie sehen, dass sie genau dieses Problem lösen soll. Es wird überprüft, ob die Verbindung offen und bereit ist. In diesem Fall wird der Befehl sofort ausgelöst. Wenn nicht, registriert es den Befehl, der ausgeführt werden soll, wenn die Datenbankverbindung geöffnet wurde.
Einige der oben genannten Vorschläge empfehlen immer Ihren Putting - dropDatabase
Befehl in dem open
Handler. Dies funktioniert jedoch 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);
}
}
Mungo 4.6.0+:
mongoose.connect('mongodb://localhost/mydb')
mongoose.connection.once('connected', () => {
mongoose.connection.db.dropDatabase();
});
Das Weiterleiten eines Rückrufs an die Verbindung funktioniert nicht mehr:
TypeError: Die Eigenschaft 'commandTakeWriteConcern' von null kann nicht gelesen werden
connect
gibt ein Versprechen, so dass Sie hinzufügen können , .then((connection) => { ... });
um die mongoose.connect
. Siehe: mongoosejs.com/docs/connections.html
Da die Methode remove in der Mungobibliothek nicht mehr verwendet wird, können wir die Funktion deleteMany verwenden, ohne dass Parameter übergeben werden.
Model.deleteMany();
Dadurch werden alle Inhalte dieses bestimmten Modells gelöscht und Ihre Sammlung ist leer.
So löschen Sie alle Dokumente in einer Sammlung:
myMongooseModel.collection.drop();
wie in den Tests gesehen