Mongooseでデータベースを削除する方法は?


97

Node.jsとMongooseでデータベース作成スクリプトを準備しています。データベースがすでに存在するかどうかを確認するにはどうすればよいですか。存在する場合は、Mongooseを使用してデータベースを削除(削除)できますか?

マングースで落とす方法が見つかりませんでした。


回答:


166

mongooseからコレクションを削除する方法はありません。できることは、コンテンツを削除することです。

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

しかし、これに使用できるmongodbネイティブjavascriptドライバーにアクセスする方法があります。

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

警告

問題が発生した場合に備えて、これを試す前にバックアップを作成してください。


2
2番目のオプションを試すと、「undefinedのプロパティ 'collectionName'を読み取れません」
Yaron Naveh

1
すべてのコレクションはハッシュmongoose.connection.collections内にあるので、単にそれらをリストする(mongoose.connection.collectionsのコレクション){mongoose.connection.collections [collection] .drop} ...似ている
drinchev

3
タイプミスがあります-function(err)の後に余分なコンマがあります... mongoose.connection.collections ['collectionName']。drop(function(err){console.log( 'collection Drop') ;});
arxpoetica 2012

3
この答えがデータベースを削除する方法の問題に対処していないことに気付いたのは私だけですか?コレクションを削除するように要求するのではなく、データベースを削除するように要求する
。–

3
「マングースからコレクションを削除する方法はありません」、最初にOPはデータベースではなく、コレクションを削除したいと考えています。次に、以下の@hellslamの答えがうまくいきます。
SCBuergel.eth 2017

79

Mongooseは、データベースが接続に存在しない場合にデータベースを作成します。接続を確立したら、クエリを実行して、データベースに何かがあるかどうかを確認できます。

接続しているデータベースはすべて削除できます。

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

1
私は試しmongoose.connection.db.dropDatabase()ましたが、dbがまだそこにあることがわかりましたか?私は何かを逃していますか?
Freewind

後で接続すると、空ですが再作成されます。落とした後にコレクションはありましたか?
hellslam

全体で同じ接続を使用していますか、それとも複数の接続を作成していますか?
hellslam、2012年

12
私が見つかりました。dropDatabase呼び出しは、コールバックの中に置かれるべきであるconnectとして、mongoose.connect('...', function() { ...dropDatabase()})
Freewind、2012年

1
dropDatabaseが機能しない場合がありますが、直接のmongoコマンドを引き続き使用できます mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function(err, result) { if (err) { console.log(err); } done(); });
farincz

14

@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);
chovy

2
これは役に立ちました、ありがとう!ただし、変数名は少し誤解を招きやすい... mongoose.connect実際にはを返しますmongoose。代わりにconn = mongoose.connect(...)書いmongoose.connect(...)てからconn = mongooose.connection
2013

connectは非同期なので、このコードが常に機能するとは思いません。そのため、接続がすぐに行われない場合、dropDatabase()コマンドは失敗します。これが、上記の他のソリューションdropDatabaseconnectステートメントまたはopenイベントハンドラーへのコールバックにコマンドを配置することを推奨した理由です。
Mark Stosberg、

8

@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


7

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オプションを使用して新しい接続ロジックを選択してください。ただし、既存のコードベースをアップグレードする場合は、最初に接続をテストしてください。


5

他のソリューションで私が抱えていた問題は、インデックスを再び機能させたい場合、アプリケーションの再起動に依存していることです。

私のニーズ(つまり、すべてのコレクションを核テストしてユニットテストを実行し、それらのインデックスと共にそれらを再作成できる)のために、私は最終的にこのソリューションを実装しました。

これは、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')
    })
  })
})

4

データベースの特定のコレクションを空にするには:

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

注意:

  1. 特定のスキーマ(削除するコレクションのスキーマ)を参照するモデルを選択します。
  2. この操作では、コレクション名はデータベースから削除されません。
  3. これにより、コレクション内のすべてのドキュメントが削除されます。

4

これはマングースの時点で私にとってはうまくいきv4.7.0ます:

mongoose.connection.dropDatabase();

4

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

2

Mongoose 4.6.0以降:

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

接続するためのコールバックを渡すことはもう機能しません:

TypeError:nullのプロパティ 'commandsTakeWriteConcern'を読み取れません


1
connectあなたが追加することができますので、約束を返す.then((connection) => { ... });mongoose.connect。参照:mongoosejs.com/docs/connections.html
Andre M

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

0

removeメソッドはmongooseライブラリで廃止されているため、パラメーターを渡さずにdeleteMany関数を使用できます。

Model.deleteMany();

これにより、この特定のモデルのすべてのコンテンツが削除され、コレクションは空になります。


0

コレクション内のすべてのドキュメントを削除するには:

await mongoose.connection.db.dropDatabase();

この回答は、mongooseのindex.d.tsファイルに基づいています。

dropDatabase(): Promise<any>;

-2

コレクション内のすべてのドキュメントを削除する場合:

myMongooseModel.collection.drop();

テストで見られるように

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.