从JavaScript对象中删除属性,由Mongoose的"findOneAndUpdate"方法返回

Zac*_*ura 21 javascript mongoose node.js

我正在Node.js上用JavaScript编写一个简单的服务器,其中(除其他外)允许用户管理他们的帐户(基本的CRUD功能等).服务器连接到MongoDB实例,使用Mongoose来管理连接和数据.

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;
Run Code Online (Sandbox Code Playgroud)

为清楚起见,Envelope(在这种情况下,a 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"}}

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

谢谢!

Wir*_*rie 58

user从调用返回的参数是a的实例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));
Run Code Online (Sandbox Code Playgroud)

  • +1我没有意识到`toObject()`存在,我们在找到它之前使用`JSON.parse(JSON.stringify(obj));`. (2认同)

Pet*_*ons 53

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

mongodb允许查询指定数据库应在响应对象中发回的属性.Mongoose通过几个方面支持这一点,包括显式字段列表以及模式中默认情况下可以选择每个属性的概念.因此,对于此用例,最好的办法是将密码字段设置为默认取消选择:

var userSchema = new mongoose.Schema({
  passwordHash: {type: String, select: false}
  ...
});
Run Code Online (Sandbox Code Playgroud)

然后你知道它永远不会自动回来.但是,当您实际处理登录请求时,您确实需要它,在这种情况下您明确请求它:

User.findOne({email: theEmail}, '+passwordHash', callback);
Run Code Online (Sandbox Code Playgroud)

对于恼人的_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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,在OP报告成功完成的评论select: false_id.如果这没有问题,这是一个很好的清洁解决方案.我没试过,但我担心它可能会破坏一些东西.

  • 要添加多个,请在第二个参数中用空格分隔它们:`'+ prop1 + prop2'` (3认同)