88

Mongoose throw an error i.e, "MongoError: ns not found" when i try to drop collection.

Here is my mongoose code:

var mongoose = require('bluebird').promisifyAll(require('mongoose'));
......
......
......   
mongoose.connection.db.dropCollection("myCollection",function(err,affect){
   console.log('err',err);

})

Error:

err { [MongoError: ns not found]
name: 'MongoError',
message: 'ns not found',
ok: 0,
errmsg: 'ns not found' }

vineet
  • 13,832
  • 10
  • 56
  • 76
  • 1
    You're not connecting to the database (using `mongoose.connect()`). – robertklep May 10 '16 at 10:51
  • mongoose doesn't have drop collection method. chekout [this](http://stackoverflow.com/a/10088410/2165143) answer for more info. – Rajesh Dhiman May 10 '16 at 10:52
  • yes, i have used mongoose.connect(). @robertklep – vineet May 10 '16 at 11:29
  • @RajeshDhiman, mongoose.connection.db.dropCollection method has used, http://stackoverflow.com/questions/11453617/mongoose-js-remove-collection-or-db?answertab=active#tab-top – vineet May 10 '16 at 11:33

5 Answers5

129

MongoError: ns not found occurs when performing actions on collections that don't exist.

For example, attempting to drop indexes before an explicit collection creation has occurred or before adding a document to the collection which implicitly creates the collection.

Andrew Homeyer
  • 7,937
  • 5
  • 33
  • 26
9

Status(ErrorCodes::NamespaceNotFound, "ns not found"); is thrown when you try to drop a collection, a view or an index that doesn't exist.

For example: _dropCollection

Other than that, there is no need to explicitly check if a collection already exists before doing any CRUD operations.

Adam Rosenthal
  • 458
  • 5
  • 9
5

This is my mongodb connection interface to avoid drop collection error:

'use strict';

module.exports = class {
    static async connect() {
        this.mongoose = require('mongoose');

        await this.mongoose.connect(process.env.MONGODB_DSN, {
            useNewUrlParser: true,
            reconnectTries: Number.MAX_VALUE,
            reconnectInterval: 5000,
            useFindAndModify: false
        }).catch(err => {
            console.error('Database connection error: ' + err.message);
        });

        this.db = this.mongoose.connection.db;

        return this.db;
    }

    static async dropCollection(list) {
        if (list.constructor.name !== 'Array') {
            list = [list];
        }

        const collections = (await this.db.listCollections().toArray()).map(collection => collection.name);

        for (let i = 0; i < list.length; i++) {
            if (collections.indexOf(list[i]) !== -1) {
                await this.db.dropCollection(list[i]);
            }
        }
    }
};
Lito
  • 1,262
  • 2
  • 17
  • 25
  • 1
    Wouldn't it be better to just catch the error if the error is a collection not found error? – programmerRaj Jul 31 '22 at 02:56
  • There's a race condition if two similar clients are trying to do the same thing. Both clients could see that the collection exists and both clients could decide to drop it, and one client will get an error. This is because `listCollections` and `dropCollection` are distinct requests made to the database, and requests from other clients may be interleaved. – Wyck Nov 10 '22 at 14:39
0

This is how I check the collection exists, before attempting to drop.

if (db.listCollections().toArray().includes(collection)) {
   await db.collection(collection).drop();
}
Dan
  • 9
  • 2
  • 2
    Not sure where you're running it, but in node.js I needed to have `if (await db.listCollection().toArray().map(c=>c.name).includes(collection)) { ...` – Scadge Oct 27 '22 at 16:46
0

Get the list of collections in an async function:

(await db.listCollections().toArray()).find(c => c.name === 'myCollection');

If not exists, it returns undefined, otherwise a CollectionInfo object as for example:

{
  name: 'myCollection',
  type: 'view',
  options: { viewOn: '...', pipeline: [ [Object] ] },
  info: { readOnly: true }
}
Wtower
  • 18,848
  • 11
  • 103
  • 80