Mongoose ile bir veritabanı nasıl açılır?


Yanıtlar:


166

Firavun faresinden bir koleksiyon düşürmenin bir yöntemi yoktur, yapabileceğiniz en iyi şey birinin içeriğini kaldırmaktır:

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

Ancak bunun için kullanılabilecek mongodb yerel javascript sürücüsüne erişmenin bir yolu vardır.

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

Uyarı

Bir şeyler ters giderse diye bunu denemeden önce bir yedek alın!


2
Ben olsun ikinci seçeneği çalıştığınızda "tanımsız malı 'collectionName' okuyamaz"
Yaron Naveh

1
Tüm koleksiyonlar mongoose.connection.collections içinde olduğundan, bunları (koleksiyon mongoose.connection.collections) {mongoose.connection.collections [koleksiyon] .drop} ... benzer
drinchev

3
Bir yazım hatası aldınız - işlevden sonra fazladan bir virgül (err) ... şöyle olmalıdır: mongoose.connection.collections ['koleksiyonAdı']. Drop (function (err) {console.log ('koleksiyon düştü') ;});
arxpoetica

3
Bu cevabın bir veri tabanının nasıl kaldırılacağı sorusunu ele almadığını fark eden tek kişi ben miyim? Bir koleksiyon düşürmek istemiyor, veritabanını düşürmek istiyor ..
Joseph Persie

3
"Firavun farından bir koleksiyonu düşürmenin bir yöntemi yoktur", her şeyden önce OP bir veritabanını silmek istiyor, bir harmanlamayı değil, ikinci olarak @ hellslam'ın aşağıdaki cevabı iyi çalışıyor.
SCBuergel.eth

79

Mongoose, bağlantıda zaten mevcut değilse bir veritabanı oluşturacaktır, bu nedenle bağlantıyı kurduğunuzda, içinde bir şey olup olmadığını görmek için onu sorgulayabilirsiniz.

Bağlı olduğunuz herhangi bir veritabanını bırakabilirsiniz:

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

1
Denedim mongoose.connection.db.dropDatabase()ama db'nin hala orada olduğunu buldum? Bir şey mi özledim?
Freewind

Daha sonra ona bağlanırsanız, boş olsa da yeniden oluşturulur. Düşürdükten sonra içinde herhangi bir koleksiyon var mıydı?
hellslam

Baştan sona aynı bağlantıyı mı kullanıyorsunuz yoksa birden fazla bağlantı mı oluşturuyorsunuz?
hellslam

12
dropDatabaseÇağrının connect, olarak geri aramasına yerleştirilmesi gerektiğini buldum mongoose.connect('...', function() { ...dropDatabase()}).
Freewind

1
dropDatabase bazı durumlarda çalışmıyor gibi görünüyor, ancak doğrudan mongo komutu hala kullanılabilir mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function(err, result) { if (err) { console.log(err); } done(); });
farincz

14

@ Hellslam'ın çözümünü bu şekilde değiştirirseniz işe yarayacaktır.

Entegrasyon testlerimden sonra Veritabanını bırakmak için bu tekniği kullanıyorum

//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 en azından benim için yaptı, bu yüzden paylaşmaya karar verdim =)


bununla db düşürmek mümkün mü? db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);
chovy

2
Bu yardımcı oldu, teşekkürler! Bununla birlikte, değişken isimleriniz biraz yanıltıcıdır ... mongoose.connectaslında geri döner mongoose. Bunun yerine conn = mongoose.connect(...)yazacağım mongoose.connect(...)ve sonra conn = mongooose.connection.
ücretli bir inek

connectAsenkron olduğu için bu kodun her zaman çalışacağını sanmıyorum . Dolayısıyla, bağlantı hemen gerçekleşmezse, dropDatabase () komutu başarısız olur. Bu nedenle yukarıdaki diğer çözümler, dropDatabasekomutun connectifadeye veya bir openolay işleyicisine yapılan geri aramaya koyulmasını önermiştir.
Mark Stosberg

8

@ Hellslam ve @ silverfighter'ın cevaplarını denedi. Testlerimi geciktiren bir yarış durumu buldum. Benim durumumda mocha testleri yapıyorum ve testin önceki işlevinde tüm DB'yi silmek istiyorum. İşte benim için işe yarayan şey.

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

Daha fazla https://github.com/Automattic/mongoose/issues/1469 okuyabilirsiniz


7

Sözler için bir tercihiniz varsa, 4.6.0+ için güncellenmiş bir cevap ( dokümanlara bakın ):

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

Bu kodu, firavun faresi 4.13.6 kullanarak kendi kodumda test ettim. Ayrıca, useMongoClientseçeneğin kullanımına dikkat edin ( dokümanlara bakın ). Dokümanlar şunu gösterir:

Mongoose'un varsayılan bağlantı mantığı 4.11.0 itibarıyla kullanımdan kaldırılmıştır. Lütfen useMongoClient seçeneğini kullanarak yeni bağlantı mantığını seçin, ancak mevcut bir kod tabanını yükseltiyorsanız önce bağlantılarınızı test ettiğinizden emin olun!


5

Diğer çözümlerde yaşadığım zorluk, dizinlerin tekrar çalışmasını istiyorsanız, uygulamanızı yeniden başlatmaya dayanmalarıdır.

İhtiyaçlarım için (yani, tüm koleksiyonları bir birim testi çalıştırabilmek, ardından indeksleriyle birlikte yeniden oluşturabilmek), bu çözümü uyguladım:

Bu dayanıyor underscore.js ve async.js bu kitaplığa karşıyız ama geliştirici için bir kullanıcıta olarak bu bırakırsanız Parellel dizinleri birleştirmek için kütüphaneler, bu çözülmeye başladı.

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

Bir veritabanındaki belirli bir koleksiyonu boşaltmak için:

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

Not:

  1. Belirli bir şemaya (silmek istediğiniz koleksiyon şeması) başvuran bir model seçin.
  2. Bu işlem koleksiyon adını veritabanından silmez.
  3. Bu, bir koleksiyondaki tüm belgeleri siler.

4

Bu benim için Mongoose olarak çalışıyor v4.7.0:

mongoose.connection.dropDatabase();

4

Veritabanınızı Mongoose'a bırakmanın en iyi yolu, kullandığınız Mongoose sürümüne bağlıdır. Mongoose'un 4.6.4 veya daha yeni bir sürümünü kullanıyorsanız, o sürümde eklenen bu yöntem sizin için muhtemelen iyi çalışacaktır:

mongoose.connection.dropDatabase();

Daha eski sürümlerde bu yöntem mevcut değildi. Bunun yerine, doğrudan bir MongoDB araması kullanacaktınız:

mongoose.connection.db.dropDatabase();

Ancak, bu veritabanı bağlantısı oluşturulduktan hemen sonra çalıştırılırsa, sessizce başarısız olabilir. Bu, bağlantının asenkron olması ve komut gerçekleştiğinde henüz kurulmaması ile ilgilidir. Bu normalde .find(), bağlantı açılana kadar kuyruğa girip ardından çalıştırılan diğer Mongoose çağrıları için bir sorun değildir .

İçin kaynak koduna bakarsanız dropDatabase()Eklenen kısayolun tam olarak bu sorunu çözmek için tasarlandığını görebilirsiniz. Bağlantının açık ve hazır olup olmadığını kontrol eder. Eğer öyleyse, komutu hemen çalıştırır. Değilse, veritabanı bağlantısı açıldığında çalıştırılacak komutu kaydeder.

Önerilerden bazıları yukarıda tavsiye daima senin koyarak dropDatabasekomutunu openişleyicisi. Ancak bu, yalnızca bağlantı henüz açılmadığında çalışır.

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

İşte yukarıdaki mantığın daha önceki Mongoose sürümleriyle kullanılabilen basit bir sürümü:

// 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

Firavun Faresi 4.6.0+:

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

Bağlanmak için bir geri arama iletmek artık işe yaramayacak:

TypeError: null değerinin 'commandsTakeWriteConcern' özelliği okunamıyor


1
connectekleyebilmeniz .then((connection) => { ... });için bir söz verir mongoose.connect. Bakınız: 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

Mongoose kitaplığında kaldırma yöntemi amortismana tabi tutulduğundan, deleteMany işlevini hiçbir parametre geçirmeden kullanabiliriz.

Model.deleteMany();

Bu, bu belirli Modelin tüm içeriğini silecek ve koleksiyonunuz boş olacaktır.


0

Tüm belgeleri bir koleksiyona bırakmak için:

await mongoose.connection.db.dropDatabase();

Bu cevap firavun faresi index.d.ts dosyasına dayanmaktadır:

dropDatabase(): Promise<any>;

-2

Bir koleksiyondaki tüm belgeleri bırakmak için:

myMongooseModel.collection.drop();

testlerde görüldüğü gibi

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.