我有以下简单的谢谢:
var userSchema = new Schema({
name : String,
age: Number,
_creator: Schema.ObjectId
});
var User = mongoose.model('User',userSchema);
我想要做的是创建新文档并返回客户端,但我想从一个中排除'creator'字段:
app.post('/example.json', function (req, res) {
var user = new User({name: 'John', age: 45, _creator: 'some ObjectId'});
user.save(function (err) {
if (err) throw err;
res.json(200, {user: user}); // how to exclude the _creator field?
});
});
最后,我想发送没有_creator字段的新创建用户:
{
name: 'John',
age: 45
}
是否可以在没有额外查找请求的情况下进行猫鼬?
P.S :最好通过
来实现答案 0 :(得分:68)
在架构级别处理此问题的另一种方法是覆盖模型的toJSON。
UserSchema.methods.toJSON = function() {
var obj = this.toObject()
delete obj.passwordHash
return obj
}
我遇到了这个问题,寻找一种方法从我提供给客户端的json中排除密码哈希,select: false
打破了我的verifyPassword函数,因为它根本没有从数据库中检索值
答案 1 :(得分:56)
记录的方式是
UserSchema.set('toJSON', {
transform: function(doc, ret, options) {
delete ret.password;
return ret;
}
});
更新 - 您可能希望使用白名单:
UserSchema.set('toJSON', {
transform: function(doc, ret, options) {
var retJson = {
email: ret.email,
registered: ret.registered,
modified: ret.modified
};
return retJson;
}
});
答案 2 :(得分:17)
当我试图找到与pymongo类似的答案时遇到你的问题。事实证明,在mongo shell中,使用find()函数调用,您可以传递第二个参数,该参数指定结果文档的外观。当您传递属性值为0的字典时,您将在此查询中出现的所有文档中排除此字段。
例如,在您的情况下,查询将如下:
db.user.find({an_attr: a_value}, {_creator: 0});
它将为您排除_creator参数。
在pymongo中,find()函数几乎相同。不知道它是如何转化为猫鼬的。我认为与之后手动删除字段相比,这是一个更好的解决方案。
希望它有所帮助。
答案 3 :(得分:11)
您可以在文档上调用toObject()
将其转换为可以自由修改的普通JS对象:
user = user.toObject();
delete user._creator;
res.json(200, {user: user});
答案 4 :(得分:11)
我会使用lodash实用程序.pick() 或 .omit()
var _ = require('lodash');
app.post('/example.json', function (req, res) {
var user = new User({name: 'John', age: 45, _creator: 'some ObjectId'});
user.save(function (err) {
if (err) throw err;
// Only get name and age properties
var userFiltered = _.pick(user.toObject(), ['name', 'age']);
res.json(200, {user: user});
});
});
另一个例子是:
var _ = require('lodash');
app.post('/example.json', function (req, res) {
var user = new User({name: 'John', age: 45, _creator: 'some ObjectId'});
user.save(function (err) {
if (err) throw err;
// Remove _creator property
var userFiltered = _.omit(user.toObject(), ['_creator']);
res.json(200, {user: user});
});
});
答案 5 :(得分:5)
通过遵循MongoDB文档,您可以通过将第二个参数传递给查询来排除字段,如:
User.find({_id: req.user.id}, {password: 0})
.then(users => {
res.status(STATUS_OK).json(users);
})
.catch(error => res.status(STATUS_NOT_FOUND).json({error: error}));
在这种情况下,密码将从查询中排除。
答案 6 :(得分:1)
我正在使用Mongoosemask,我很高兴。
它支持根据您的需要隐藏和公开其他名称的属性
https://github.com/mccormicka/mongoosemask
var maskedModel = mongomask.mask(model,['name','age']); //你完成了
答案 7 :(得分:0)
您可以在架构文件本身上执行此操作。
// user.js
var userSchema = new Schema({
name : String,
age: Number,
_creator: Schema.ObjectId
});
userSchema.statics.toClientObject = function (user) {
const userObject = user?.toObject();
// Include fields that you want to send
const clientObject = {
name: userObject.name,
age: userObject.age,
};
return clientObject;
};
var User = mongoose.model('User',userSchema);
现在,在您响应客户端的控制器方法中,执行以下操作
return res.json({
user: User.toClientObject(YOUR_ENTIRE_USER_DOC),
});