Проверьте, существует ли идентификатор в коллекции с помощью мангуста

Например, у меня есть коллекция User:

var mongoose = require('mongoose');

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

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

А потом у меня есть ID:

var userID = "some-user-id"

Каков правильный способ проверить, существует ли этот идентификатор в коллекции User. Мне не нужно это читать файл или возвращать его, мне просто нужно значение true или false.

Вот один из способов его достижения:

User.findOne({
     _id: userID
}, function (err, existingUser) {

Но есть ли более быстрый и эффективный способ?

Ответ 1

Используйте count, а не findOne.

Это (под капотом) заставит мангуста использовать find: http://docs.mongodb.org/manual/reference/method/db.collection.count

findOne() будет читать + возвращать документ, если он существует С другой стороны, find() просто возвращает курсор (или нет) и только считывает данные, если вы перебираете курсор. Поэтому в нашем случае мы не перебираем курсор, просто подсчитываем возвращаемые результаты.

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

Ответ 2

Принятый ответ подходит для небольших коллекций.

Более быстрый способ для больших коллекций - просто использовать это:

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

Он не вернет все поля. Я полагаю, что в настоящее время они работают над новой функцией, поддерживающей то, что вы (и я) хотите.


Тем временем вы можете создать плагин, очень простой и многократно используемый.

Создайте файл any.js с этим кодом:

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

Затем в вашей модели вы делаете это:

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

... и используйте его так:

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

Ответ 3

Теперь вы можете использовать User.exists() с сентября 2019 года следующим образом:

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

Из документов:

Под капотом MyModel.exists({ answer: 42 }) эквивалентно MyModel.findOne({ answer: 42 }).select({ _id: 1 }).lean().then(doc => !!doc)