从Mongoose的“findOneAndUpdate”方法返回的JavaScript对象中删除属性

我在Node.js上用JavaScript编写了一个简单的服务器,这个服务器允许用户pipe理他们的帐户(基本的CRUDfunction等等)。 服务器连接到一个MongoDB实例,使用Mongoose来pipe理连接和数据。

Mongoose中的模型有一个名为findOneAndUpdate()的方法,它的确如你所想的那样:查询返回的第一个文档的数据库,并根据传递的参数更新所述文档。 然后它将新的,更新的文档返回给用户。 它完全按照预期工作,我没有问题。

但是,我不希望返回所有的用户数据。 具体来说,我想省略_idpassword字段。 由于MongoDB返回的对象是一个基本的JavaScript对象,我认为我可以通过调用delete object.attribute来删除这些属性。 不幸的是,由于某种原因,这是行不通的。

这是我的代码,更新用户信息:

 case "update": User.findOneAndUpdate({"token": header.token}, body, function(err, user) { if (err) { return callback(err); } else { delete user["_id"]; delete user["password"]; return callback(null, new SuccessEnvelope(user)); } }); break; 

为了清楚起见, Envelope (在这种情况下是SuccessEnvelope )是客户端和服务器为了促进通信而需要的信息束。 类似于TCP数据包。 无论如何,我离题了

例如,如果我想更新我的用户名从“joe_bob”到“jim_bob”,我会发送到服务器:

{"header": "type": "user", "method": "update", "token": "IM_A_TOKEN_GAIS_SRSLY"}, "body": {"username": "jim_bob"}}

而用户的用户名更新成功,这是我得到的回报:

{"header": {"type": "success"}, "body": {"__v": 0, "_id":"SOME_NUMERICAL_ID", "email": "joe_bob@email.com", "password": "SUPER_SECURE_PASSWORD_HASH_COME_AT_ME_NSA", "token": "IM_A_TOKEN_GAIS_SRSLY", "username": "jim_bob"}}

正如你所看到的, _idpassword仍然存在。 我究竟做错了什么? 任何帮助将不胜感激。

谢谢!

在架构中为通常不需要的属性设置select:false

mongodb允许查询指定数据库应该在响应对象中发回的属性。 Mongoose支持这几个东西,包括明确的字段列表,以及模式中的每个属性可以被默认select的概念。 所以对于这个用例,最好的办法是将你的密码字段设置为默认取消select:

 var userSchema = new mongoose.Schema({ passwordHash: {type: String, select: false} ... }); 

那么你知道它永远不会自动回来。 但是,当您真正去处理login请求时,您确实需要它,在这种情况下,您明确要求:

 User.findOne({email: theEmail}, '+passwordHash', callback); 

对于恼人的_id属性,使用模式转换

_id事情导致很多人头疼。 Mongoose直接在文档中解决这个问题:

 // specify the transform schema option if (!schema.options.toObject) schema.options.toObject = {}; schema.options.toObject.transform = function (doc, ret, options) { // remove the _id of every document before returning the result delete ret._id; } 

请注意,在OP报告成功执行的注释中,对于_id select: false 。 如果这没有问题,这是一个很好的干净的解决scheme。 我没有尝试过,但是我担心它可能会破坏一些东西。

从调用返回的user参数是Model一个实例,在这种情况下是User

如果你想使用它作为一个原始的JavaScript对象,那么你需要使用toObject来转换它。 这将返回一个普通的JavaScript对象。 有了这个,你可以使用delete和删除任何你想要的属性。

 user = user.toObject(); // swap for a plain javascript object instance delete user["_id"]; delete user["password"]; return callback(null, new SuccessEnvelope(user));