80

Is it possible to remove collection or entire db using mongoose.js?

WHITECOLOR
  • 24,996
  • 37
  • 121
  • 181

7 Answers7

111

This can now be done in Mongoose.

MyModel.collection.drop();

Hat tip: https://github.com/Automattic/mongoose/issues/4511

David L. Walsh
  • 24,097
  • 10
  • 61
  • 46
  • 1
    Is there a way to do this with promises? – JohnK Aug 05 '19 at 13:49
  • 2
    @JohnK: `await MyModel.collection.drop();`. The more interesting question is, how do you only drop if the collection exists? Otherwise, you'll get a misleading and cryptic [`MongoError: ns not found`](https://stackoverflow.com/questions/37136204/mongoerror-ns-not-found-when-try-to-drop-collection#comment99306970_44488227). – Dan Dascalescu Apr 12 '20 at 07:52
  • @DanDascalescu you can `catch` the error the promise returns. `await MyModel.collection.drop().then(() => { ... }).catch(() => { ... })` – m.e.conroy Apr 13 '21 at 15:07
  • This is the highest rated answer but not treating this as a promise will cause problems if you are seeding something complex. I called this and then began my recursive seed function. Drop actually happened in the middle of my seed, so many of my items were missing. It let to a lot of confusion. Use .then() – Peege151 Nov 05 '22 at 19:08
106

Yes, although you do it via the native MongoDB driver and not Mongoose itself. Assuming a required, connected, mongoose variable, the native Db object is accessible via mongoose.connection.db, and that object provides dropCollection and dropDatabase methods.

// Drop the 'foo' collection from the current database
mongoose.connection.db.dropCollection('foo', function(err, result) {...});

// Drop the current database
mongoose.connection.db.dropDatabase(function(err, result) {...});
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • 7
    Note that these methods return promises as well, so you can do things like `await mongoose.connection.db.dropCollection('foo');` instead of struggling with callbacks – Adam Reis Nov 11 '17 at 20:04
12

For those that are using the mochajs test framework and want to clean all db collections after each test, you can use the following which uses async/await:

afterEach(async function () {
  const collections = await mongoose.connection.db.collections()

  for (let collection of collections) {
    await collection.remove()
  }
})
adamc
  • 1,315
  • 19
  • 16
3

Mongoose references the connection on every model. So, you may find it useful to also drop the DB or collection off of an individual model.

For example:

// Drop the 'foo' collection from the current database
User.db.dropCollection('foo', function(err, result) {...});

// Drop the current database
User.db.dropDatabase(function(err, result) {...});
alucic
  • 12,492
  • 2
  • 20
  • 25
Huston Hedinger
  • 511
  • 2
  • 9
3

For 5.2.15 version of Mongoose + Mocha tests usage where you need to drop all collections before each test.

beforeEach(async () => {
     const collections = await mongoose.connection.db.collections();

     for (let collection of collections) {
          // note: collection.remove() has been depreceated.        
          await collection.deleteOne(); 
     }
});
Durja
  • 637
  • 13
  • 20
  • It's much safer to drop collections `before` executing instead of after incase execution is interrupted between test runs or data exists in the database already from manual testing. – fIwJlxSzApHEZIl Sep 24 '21 at 20:17
2

If want to drop collection after tests and your test were running in a docker container:

mongoose = require("mongoose");
...
afterAll(async () => {
  const url = 'mongodb://host.docker.internal:27017/my-base-name';
  await mongoose.connect(url)
  await mongoose.connection.collection('collection-name').drop()
})
Vitalii Andrusishyn
  • 3,984
  • 1
  • 25
  • 31
-1

I dropped my collections using Connection.prototype.dropCollection()

const conn = mongoose.createConnection('mongodb://localhost:27017/mydb');
conn.dropCollection("Collection_name",callbacks);