需要Mongoose.js上的几个列之一

try*_*sis 10 mongoose mongodb node.js express passport.js

是否有任何方法只需要Mongoose.js中单个集合中的一个(或多个,但不是全部)几列?在我的情况下,我使用Passport并希望我的用户通过我提供的提供商之一注册,或者自己创建.但是,我不想要求用户通过任何一个提供商注册,而是要求他/她希望的任何一个提供商.

这里有一个简单的模式,从scotch.io护照上的教程(:这是一个例子,我不打算在我的应用程序使用它,但可能会使用类似的东西):

// app/models/user.js
// load the things we need
var mongoose = require('mongoose');
var bcrypt   = require('bcrypt-nodejs');

// define the schema for our user model
var userSchema = mongoose.Schema({

    local            : {
        email        : String,
        password     : String,
    },
    facebook         : {
        id           : String,
        token        : String,
        email        : String,
        name         : String
    },
    twitter          : {
        id           : String,
        token        : String,
        displayName  : String,
        username     : String
    },
    google           : {
        id           : String,
        token        : String,
        email        : String,
        name         : String
    }

});

// methods ======================
// generating a hash
userSchema.methods.generateHash = function(password) {
    return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

// checking if password is valid
userSchema.methods.validPassword = function(password) {
    return bcrypt.compareSync(password, this.local.password);
};

// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);
Run Code Online (Sandbox Code Playgroud)

我如何让它要求的对象的至少一个local,facebook,twitter,或google指定(不null,不undefined,等)保存文档,而无需做出任何一个要求(也不需要其他的人),或使所有的前他们需要吗?在应用程序方面,这将使用户需要首次通过用户名和密码注册; Twitter或Facebook OAuth帐户或Google+ OpenID帐户.但是,用户不会被绑定到任何一个提供商,因此他/她不必通过用户名和密码注册,但如果不是他/她,他/她也不必通过社交网络帐户注册事情.

Ben*_*wer 4

我会尝试使用全局预验证挂钩:

const providers = ['google', 'twitter', 'facebook', 'local'];

userSchema.pre('validate', function(next) {
 let hasProvider = false;

 // not sure if this is needed, but sometimes, the scoping is messed up
 const that = this;

 // you should add more validations, e.g. for fields, too
 hasProvider = providers.some(provider => that.hasOwnProperty(provider));

 return (hasProvider) ? next() : next(new Error('No Provider provided'));
});
Run Code Online (Sandbox Code Playgroud)

注意:只有在实际调用预验证挂钩时,这才有效。如果您只使用的话,.save()根据文档应该没问题:

save() 函数会触发 validate() 挂钩,因为 mongoose 有一个内置的 pre('save') 挂钩来调用 validate()。这意味着所有 pre('validate') 和 post('validate') 挂钩都会在任何 pre('save') 挂钩之前调用。

如果您使用绕过验证的函数,则可能会导致问题。检查https://mongoosejs.com/docs/validation.html了解更多信息!