Check if ID exists in a collection with mongoose

You can now use User.exists() as of September 2019 like so:

const doesUserExit = await User.exists({ _id: userID });

From the docs:

Under the hood, MyModel.exists({ answer: 42 }) is equivalent to MyModel.findOne({ answer: 42 }).select({ _id: 1 }).lean().then(doc => !!doc)


The accepted answer is fine for small collections.

A faster way on larger collections is to simply use this:

const result = await User.findOne({ _id: userID }).select("_id").lean();
if (result) {
    // user exists...
}

// or without "async/await":

User.findOne({ _id: userID }).select("_id").lean().then(result => {
    if (result) {
        // user exists...
    }
});

It won't return all fields. I believe they are currently working on a new feature to support what you (and I) want.


In the meantime you could create a plugin, very simple and reusable.

Create an any.js file with this code:

module.exports = function any(schema, options) {
    schema.statics.any = async function (query) {
        const result = await this.findOne(query).select("_id").lean();
        return result ? true : false;
      };
  }

Then in your model you do this:

var mongoose = require('mongoose');
const any = require('./plugins/any'); // I'm assuming you created a "plugins" folder for it

var UserSchema = new mongoose.Schema({
    email: String,
    googleId: String,
    facebookId: String,
    displayName: String,
    active: Boolean
});

UserSchema.plugin(any);
module.exports = mongoose.model('User', UserSchema);

...and use it like this:

const result = await User.any({ _id: userID });
if (result) {
    // user exists...
}

// or without using "async/await":

User.any({ _id: userID }).then(result => {
    if (result) {
        // user exists...
    }
});

Use count rather than findOne.

This will (under the hood) cause mongoose to use find : http://docs.mongodb.org/manual/reference/method/db.collection.count

findOne() will read + return the document if it exists On the other hand, find() just returns a cursor (or not) and only reads the data if you iterate over the cursor. So in our case, we're not iterating over the cursor, merely counting the results returned.

User.countDocuments({_id: userID}, function (err, count){ 
    if(count>0){
        //document exists });
    }
});