回答:
mongooseからコレクションを削除する方法はありません。できることは、コンテンツを削除することです。
Model.remove({}, function(err) {
console.log('collection removed')
});
しかし、これに使用できるmongodbネイティブjavascriptドライバーにアクセスする方法があります。
mongoose.connection.collections['collectionName'].drop( function(err) {
console.log('collection dropped');
});
問題が発生した場合に備えて、これを試す前にバックアップを作成してください。
Mongooseは、データベースが接続に存在しない場合にデータベースを作成します。接続を確立したら、クエリを実行して、データベースに何かがあるかどうかを確認できます。
接続しているデータベースはすべて削除できます。
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()
ましたが、dbがまだそこにあることがわかりましたか?私は何かを逃していますか?
dropDatabase
呼び出しは、コールバックの中に置かれるべきであるconnect
として、mongoose.connect('...', function() { ...dropDatabase()})
。
mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function(err, result) { if (err) { console.log(err); } done(); });
@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は少なくとも私には効果があったので、共有することにしました=)
db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);
mongoose.connect
実際にはを返しますmongoose
。代わりにconn = mongoose.connect(...)
書いmongoose.connect(...)
てからconn = mongooose.connection
。
connect
は非同期なので、このコードが常に機能するとは思いません。そのため、接続がすぐに行われない場合、dropDatabase()コマンドは失敗します。これが、上記の他のソリューションdropDatabase
がconnect
ステートメントまたはopen
イベントハンドラーへのコールバックにコマンドを配置することを推奨した理由です。
@hellslamと@silverfighterの回答を試してみました。テストを妨げる競合状態が見つかりました。私の場合、モカテストを実行しており、テストのbefore関数でDB全体を消去したいと考えています。ここに私のために働くものがあります。
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
4.6.0以降で、promiseを優先する場合の更新された回答(docsを参照):
mongoose.connect('mongodb://localhost/mydb', { useMongoClient: true })
.then((connection) => {
connection.db.dropDatabase();
// alternatively:
// mongoose.connection.db.dropDatabase();
});
このコードは、mongoose 4.13.6を使用して自分のコードでテストしました。また、useMongoClient
オプションの使用に注意してください(docsを参照)。ドキュメントは以下を示します:
Mongooseのデフォルトの接続ロジックは4.11.0で非推奨になりました。useMongoClientオプションを使用して新しい接続ロジックを選択してください。ただし、既存のコードベースをアップグレードする場合は、最初に接続をテストしてください。
他のソリューションで私が抱えていた問題は、インデックスを再び機能させたい場合、アプリケーションの再起動に依存していることです。
私のニーズ(つまり、すべてのコレクションを核テストしてユニットテストを実行し、それらのインデックスと共にそれらを再作成できる)のために、私は最終的にこのソリューションを実装しました。
これは、underscore.jsおよびasync.jsライブラリーを使用して、インデックスを並列に組み立てます。そのライブラリーに反対している場合は、巻き戻しができる可能性がありますが、開発者のための演習として残しておきます。
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')
})
})
})
これはマングースの時点で私にとってはうまくいきv4.7.0
ます:
mongoose.connection.dropDatabase();
Mongooseでデータベースを削除する最良の方法は、使用しているMongooseのバージョンによって異なります。4.6.4以降のバージョンのMongooseを使用している場合、そのリリースで追加されたこのメソッドはおそらく正常に機能します。
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);
}
}
Mongoose 4.6.0以降:
mongoose.connect('mongodb://localhost/mydb')
mongoose.connection.once('connected', () => {
mongoose.connection.db.dropDatabase();
});
接続するためのコールバックを渡すことはもう機能しません:
TypeError:nullのプロパティ 'commandsTakeWriteConcern'を読み取れません
connect
あなたが追加することができますので、約束を返す.then((connection) => { ... });
にmongoose.connect
。参照:mongoosejs.com/docs/connections.html
removeメソッドはmongooseライブラリで廃止されているため、パラメーターを渡さずにdeleteMany関数を使用できます。
Model.deleteMany();
これにより、この特定のモデルのすべてのコンテンツが削除され、コレクションは空になります。