Saya sedang mempersiapkan skrip pembuatan database di Node.js dan Mongoose. Bagaimana cara memeriksa apakah database sudah ada, dan jika demikian, hapus (hapus) menggunakan Mongoose?
Saya tidak dapat menemukan cara untuk menjatuhkannya dengan luwak.
Saya sedang mempersiapkan skrip pembuatan database di Node.js dan Mongoose. Bagaimana cara memeriksa apakah database sudah ada, dan jika demikian, hapus (hapus) menggunakan Mongoose?
Saya tidak dapat menemukan cara untuk menjatuhkannya dengan luwak.
Jawaban:
Tidak ada metode untuk membuang koleksi dari luwak, hal terbaik yang dapat Anda lakukan adalah menghapus salah satu konten:
Model.remove({}, function(err) {
console.log('collection removed')
});
Tetapi ada cara untuk mengakses driver javascript asli mongodb, yang dapat digunakan untuk ini
mongoose.connection.collections['collectionName'].drop( function(err) {
console.log('collection dropped');
});
Buat cadangan sebelum mencoba ini jika terjadi kesalahan!
Mongoose akan membuat database jika belum ada pada koneksi, jadi setelah Anda membuat koneksi, Anda bisa menanyakannya untuk melihat apakah ada sesuatu di dalamnya.
Anda dapat menjatuhkan database apa pun yang Anda sambungkan:
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()tetapi saya menemukan db masih ada? Apakah saya melewatkan sesuatu?
dropDatabasepemanggilan harus ditempatkan di callback connect, sebagai mongoose.connect('...', function() { ...dropDatabase()}).
mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function(err, result) { if (err) { console.log(err); } done(); });
Jika Anda memodifikasi solusi @ hellslam seperti ini, maka itu akan berhasil
Saya menggunakan teknik ini untuk menjatuhkan Database setelah tes integrasi saya
//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();
Setidaknya HTH itu untuk saya, jadi saya memutuskan untuk berbagi =)
db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);
mongoose.connectsebenarnya kembali mongoose. Alih-alih conn = mongoose.connect(...)saya akan menulis mongoose.connect(...)dan kemudian conn = mongooose.connection.
connectasynchronous. Jadi jika koneksi tidak segera terjadi, perintah dropDatabase () akan gagal. Itulah mengapa solusi lain di atas merekomendasikan untuk meletakkan dropDatabaseperintah di callback ke connectpernyataan atau openpenanganan peristiwa.
Mencoba jawaban @ hellslam dan @ silverfighter. Saya menemukan kondisi balapan yang menahan tes saya. Dalam kasus saya, saya menjalankan tes mocha dan dalam fungsi tes sebelumnya saya ingin menghapus seluruh DB. Inilah yang berhasil untuk saya.
var con = mongoose.connect('mongodb://localhost/mydatabase');
mongoose.connection.on('open', function(){
con.connection.db.dropDatabase(function(err, result){
done();
});
});
Anda dapat membaca lebih lanjut https://github.com/Automattic/mongoose/issues/1469
Jawaban yang diperbarui, untuk 4.6.0+, jika Anda memiliki preferensi untuk promise ( lihat dokumen ):
mongoose.connect('mongodb://localhost/mydb', { useMongoClient: true })
.then((connection) => {
connection.db.dropDatabase();
// alternatively:
// mongoose.connection.db.dropDatabase();
});
Saya menguji kode ini dalam kode saya sendiri, menggunakan luwak 4.13.6. Juga, perhatikan penggunaan useMongoClientopsi ( lihat dokumen ). Dokumen menunjukkan:
Logika koneksi default Mongoose tidak digunakan lagi mulai 4.11.0. Silakan ikut serta ke logika koneksi baru menggunakan opsi useMongoClient, tetapi pastikan Anda menguji koneksi Anda terlebih dahulu jika Anda meningkatkan basis kode yang ada!
Kesulitan yang saya alami dengan solusi lain adalah mereka mengandalkan memulai ulang aplikasi Anda jika Anda ingin indeks berfungsi kembali.
Untuk kebutuhan saya (yaitu dapat menjalankan pengujian unit pada nukes semua koleksi, kemudian membuatnya kembali bersama dengan indeksnya), saya akhirnya menerapkan solusi ini:
Ini bergantung pada pustaka underscore.js dan async.js untuk mengumpulkan indeks dalam parellel, itu bisa dibatalkan jika Anda menentang pustaka itu tetapi saya membiarkannya sebagai latihan untuk pengembang.
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')
})
})
})
Untuk mengosongkan koleksi tertentu dalam database:
model.remove(function(err, p){
if(err){
throw err;
} else{
console.log('No Of Documents deleted:' + p);
}
});
catatan:
Ini bekerja untuk saya pada Mongoose v4.7.0:
mongoose.connection.dropDatabase();
Cara terbaik untuk meletakkan database Anda di Mongoose bergantung pada versi Mongoose yang Anda gunakan. Jika Anda menggunakan versi Mongoose 4.6.4 atau yang lebih baru, maka metode yang ditambahkan dalam rilis tersebut kemungkinan akan berfungsi dengan baik untuk Anda:
mongoose.connection.dropDatabase();
Dalam rilis yang lebih lama, metode ini tidak ada. Sebagai gantinya, Anda akan menggunakan panggilan MongoDB langsung:
mongoose.connection.db.dropDatabase();
Namun, jika ini dijalankan tepat setelah koneksi database dibuat, itu mungkin bisa gagal secara diam-diam. Ini terkait dengan koneksi yang sebenarnya asynchronous dan belum diatur ketika perintah terjadi. Ini biasanya tidak menjadi masalah untuk panggilan Mongoose lainnya seperti.find() , yang mengantri sampai koneksi terbuka dan kemudian dijalankan.
Jika Anda melihat kode sumber untuk dropDatabase() pintasan yang ditambahkan, Anda dapat melihat bahwa itu dirancang untuk menyelesaikan masalah ini dengan tepat. Ia memeriksa untuk melihat apakah koneksi terbuka dan siap. Jika demikian, itu akan segera mengaktifkan perintah. Jika tidak, ini mendaftarkan perintah untuk dijalankan ketika koneksi database telah dibuka.
Beberapa saran di atas merekomendasikan untuk selalu meletakkan dropDatabaseperintah Anda di openhandler. Tapi itu hanya berfungsi jika koneksi belum terbuka.
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;
};
Berikut adalah versi sederhana dari logika di atas yang dapat digunakan dengan versi Mongoose sebelumnya:
// 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);
}
}
Luwak 4.6.0+:
mongoose.connect('mongodb://localhost/mydb')
mongoose.connection.once('connected', () => {
mongoose.connection.db.dropDatabase();
});
Meneruskan panggilan balik untuk terhubung tidak akan berfungsi lagi:
TypeError: Tidak dapat membaca properti 'commandsTakeWriteConcern' dari null
connectmengembalikan janji, sehingga Anda dapat menambahkan .then((connection) => { ... });ke mongoose.connect. Lihat: mongoosejs.com/docs/connections.html
Karena metode penghapusan disusutkan di perpustakaan luwak, kita dapat menggunakan fungsi deleteMany tanpa parameter yang dilewatkan.
Model.deleteMany();
Ini akan menghapus semua konten Model khusus ini dan koleksi Anda akan kosong.
Untuk meletakkan semua dokumen dalam koleksi:
await mongoose.connection.db.dropDatabase();
Jawaban ini didasarkan dari file index.d.ts luwak:
dropDatabase(): Promise<any>;