【问题标题】:Check if ID exists in a collection with mongoose检查 ID 是否存在于带有 mongoose 的集合中
【发布时间】:2015-02-13 11:25:18
【问题描述】:

例如,我有一个集合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"

检查此 id 是否存在于 User 集合中的正确方法是什么。我不需要它来读取文件或返回它,我只需要 truefalse 值。

这是实现它的一种方法:

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

但是有更快更有效的方法吗?

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    使用count 而不是 findOne。

    这将(在后台)导致猫鼬使用 find : http://docs.mongodb.org/manual/reference/method/db.collection.count

    findOne() 将读取并返回文档(如果存在) 另一方面,find() 只返回一个游标(或不返回),并且仅在您遍历游标时读取数据。 所以在我们的例子中,我们不是在游标上迭代,只是计算返回的结果。

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

    【讨论】:

    • 其实。 “在引擎盖下”这使用.count() 方法。这是一种特定的方法,通常是最好的方法。尽管 .count() 实际上是 .find() 光标返回的“修饰符”,但最好实际解释这一点,而不是让它默默无闻。
    • count 现在会触发警告:“DeprecationWarning: collection.count 已弃用,将在未来版本中删除。请改用collection.countDocumentscollection.estimatedDocumentCount”。
    • 改用countDocuments()
    【解决方案2】:

    您现在可以使用 User.exists()2019 年 9 月 起,如下所示:

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

    来自docs

    在底层,MyModel.exists({ answer: 42 }) 相当于 MyModel.findOne({ answer: 42 }).select({ _id: 1 }).lean().then(doc => !!doc)

    【讨论】:

    • 尝试在预保存挂钩中使用它但获取存在不是函数 mongoose - 5.7.13
    【解决方案3】:

    接受的答案适用于小型收藏。

    一个在更大的集合上更快的方法是简单地使用这个:

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

    它不会返回所有字段。我相信他们目前正在开发 a new feature 以支持您(和我)想要的。


    与此同时,您可以创建一个非常简单且可重复使用的插件。

    使用此代码创建一个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...
        }
    });
    

    【讨论】:

      【解决方案4】:

      或者你可以简单地使用 exists 函数,而无需进行任何 async/await:

      myData = {_id: userID};
      
      User.exists(myData,(error, result)=>{
          if (error){
            console.log(error)
          } else {
            console.log("result:", result)  //result is true if myData already exists
          }
        });
      

      你现在可以玩结果了!

      【讨论】:

        【解决方案5】:
        User.exists({ _id: userID }).then(exists => {
          if (exists) {
            res.redirect('/dashboard')
          } else {
            res.redirect('/login')
          }
        })
        

        更多信息可以在Mongoose docs找到。

        【讨论】:

          猜你喜欢
          • 2018-08-11
          • 2012-11-06
          • 1970-01-01
          • 1970-01-01
          • 2019-01-21
          • 1970-01-01
          • 1970-01-01
          • 2023-02-09
          • 2013-11-13
          相关资源
          最近更新 更多