web-dev-qa-db-ja.com

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

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

Mongooseでドロップする方法が見つかりませんでした。

94
Yaron Naveh

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

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

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

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

警告

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

163
drinchev

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

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

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

このように@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少なくとも私にとってはそうだったので、共有することにしました=)

14
silverfighter

@hellslamと@silverfighterの回答を試しました。テストを遅らせる競合状態が見つかりました。私の場合、mochaテストを実行しています。テストの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

8
zafrani

約束の設定がある場合の4.6.0以降の更新された回答( 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
Andre M

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

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

これは nderscore.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')
    })
  })
})
5
Eric Caron

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

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

注意:

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

これは、Mongoose v4.7.0の時点で機能します:

mongoose.connection.dropDatabase();
4
user3344977

データベースをMongooseにドロップする最適な方法は、使用しているMongooseのバージョンによって異なります。 4.6.4以降のバージョンのMongooseを使用している場合、そのリリースで追加されたこのメソッドは、おそらくうまく機能するでしょう:

mongoose.connection.dropDatabase();

古いリリースでは、このメソッドは存在しませんでした。代わりに、MongoDBの直接呼び出しを使用します。

mongoose.connection.db.dropDatabase();

ただし、データベース接続の作成直後にこれを実行すると、サイレントに失敗する可能性があります。これは、接続が実際に非同期であり、コマンドの発生時にまだ設定されていないことに関連しています。これは通常、.find()のような他のMongoose呼び出しでは問題になりません。これは、接続が開かれて実行されるまでキューに入れられます。

追加されたdropDatabase()ショートカットのソースコードを見ると、この正確な問題を解決するために設計されたことがわかります。接続が開いて準備ができているかどうかを確認します。その場合、すぐにコマンドを実行します。そうでない場合、データベース接続が開かれたときに実行するコマンドを登録します。

上記の提案のいくつかは、alwaysdropDatabaseコマンドを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);
    }
}  
4
Mark Stosberg

Mongoose 4.6.0+:

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

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

TypeError:nullのプロパティ 'commandsTakeWriteConcern'を読み取ることができません

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