我有一个实现getter / setter的基本架构:
var User = new Schema( {
username : { type : String , required : true , get: getUsername, set: setUsername }
} );
User.set('toObject', { getters: true , virtuals : true } );
User.set('toJSON', { getters: true , virtuals : true } );
UserModel = mongoose.model('User', User);
setUsername
非常简单,但是“随机化”了用户名,显然getUsername
检索了原始值。现在,每次我调用setUsername
时,我都会得到一个不同的“随机”字符串(我的意思是这几乎是一个哈希函数)。
我的问题是,我可以以某种方式在查询中使用吸气剂吗? 喜欢
UserModel.$where( 'this.username.get() == "<somestring>"' ).exec( function( err , users ) {
// do something with the users
}
} ); // here I get MongoError: TypeError: this.username.get is not a function
或
UserModel.find( { $where: function() {
return( getUsername( this.username ) == "<somestring>" )
} } , function( err , users ) {
// do something with the users
} ); // here I get MongoError: ReferenceError: getUsername is not defined
我也尝试向架构中添加getUsername
方法,添加虚函数等,但是似乎找不到解决方案。我已经尝试了15种不同的语法,但是却收到错误消息,一个空数组或所有用户。
基本上,如果我有一个用户名是“ a” 的用户,它将以*“ b”,“ c”,“ d”或其他{ {1}}函数将其设置为。 我想只知道用户名是“ a” 的用户。
谢谢!
答案 0 :(得分:0)
是的,理论上可以使用query middleware来做到这一点,但是您可能需要有所不同:
假设您要运行这样的查询:
UserModel.find({user: 'a'})
其中'a'是未加密的输入,您实际上想自动查找{user:getUser('a')},我们将其称为{user:'b'}
然后,您可以使用此中间件来修改查询,如下所示:
const userFilter = function (next) {
const query = this.getQuery();
if (query.userName) {
// this transforms the query in-place from {user: 'a'} to {user : 'b'}
query.userName = setUserName(query.userName)};
}
return next();
};
// let's hook this one in!
User.pre('find', userFilter);
注意:这将钩住包括“ .userName”在内的所有查询。如果仅使用UserModel.find(),则该查询就足够了,但是否则,您可能还想在['count', 'find', 'findOne', 'findOneAndRemove','findOneAndUpdate', 'remove', 'update', 'updateOne', 'updateMany']
上注册该钩子,并且使用某些查询(iirc例如findByIdAndUpdate)应该绕过猫鼬并直接使用mongodbDriver,这也可能绕过该钩子……即使它目前似乎仍然可以正常工作,所以您可能想用它测试各种功能)
编辑:
回头看您的问题,我不确定是否能正确理解您的问题。 setUsername函数实际上返回什么?相同的输入是否总是相同的输出?如果是这样,您基本上总是要查询{userName: setUserName('a')}
,对吧?