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

从JavaScript对象中删除属性,由Mongoose的“findOneAndUpdate”方法返回,javascript,node.js,mongoose,Javascript,Node.js,Mongoose,我正在Node.js上用JavaScript编写一个简单的服务器,它允许用户管理其帐户的基本CRUD功能等。服务器连接到MongoDB实例,使用Mongoose管理连接和数据 Mongoose中的模型有一个名为findOneAndUpdate的方法,它的作用与您认为的完全相同:查询数据库中返回的第一个文档,并根据您传递的参数更新所述文档。然后,它将更新后的新文档返回给用户。它完全按照预期工作,我对此没有问题 但是,我不希望返回所有用户数据。具体来说,我想省略_id和password字段。由于Mo

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

Mongoose中的模型有一个名为findOneAndUpdate的方法,它的作用与您认为的完全相同:查询数据库中返回的第一个文档,并根据您传递的参数更新所述文档。然后,它将更新后的新文档返回给用户。它完全按照预期工作,我对此没有问题

但是,我不希望返回所有用户数据。具体来说,我想省略_id和password字段。由于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;
为了清楚起见,在本例中,信封successevelope是客户机和服务器为了方便通信而需要的一组信息。类似于TCP数据包。无论如何,我离题了

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

{头:类型:用户,方法:更新,令牌:IM\u A\u-token\u-GAIS\u-SRSLY},主体:{用户名:jim\u-bob}}

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

{header:{type:success},body:{uu v:0,{u id:SOME\u NUMERICAL\u id,email:joe_bob@email.com,密码:超级安全,密码,密码,密码,密码,密码,令牌:IM,令牌,用户名:jim,bob}

如您所见,_id和密码仍然存在。我做错了什么?任何帮助都将不胜感激

谢谢大家!

对于通常不需要的属性,在架构中设置select:false mongodb允许查询指定数据库应在响应对象中发回哪些属性。Mongoose通过几个方面支持这一点,包括显式字段列表,以及在模式中每个属性都可以默认选择或不选择的概念。因此,对于这个用例,最好将密码字段设置为默认取消选择:

var userSchema = new mongoose.Schema({
  passwordHash: {type: String, select: false}
  ...
});
那你就知道它永远不会自动回来。但是,当您实际处理登录请求时,您确实需要它,在这种情况下,您会明确请求它:

User.findOne({email: theEmail}, '+passwordHash', callback);
对于恼人的_id属性,请使用模式转换 这件事让很多人头疼。Mongoose通过以下方式直接解决了这一问题:

请注意,在评论OP报告中,成功地为_id执行了select:false。如果这样做没有问题,那么这是一个很好的干净解决方案。我还没有尝试过,但我担心它可能会破坏一些东西。

调用返回的用户参数是模型的一个实例,在本例中是用户

如果要将其用作原始JavaScript对象,则需要使用toObject对其进行转换。这将返回一个普通的旧JavaScript对象。这样,您就可以使用delete和remove删除您想要的任何属性

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

此外,为了补充这一点,我最终在模式中显式创建了一个_id属性,并将select属性更改为false,就像您对passwordHash属性所做的那样。要添加多个,请在第二个参数中用空格分隔它们:“+prop1+prop2”回调在哪里定义?+1我没有意识到toObject存在,我们使用的是JSON.parseJSON.stringifyobj;在找到这个之前。将我的对象转换为对象成功了。不现实,但它是有效的!我本可以花一周的时间在这上面。非常感谢你:它很有效!只是提到它必须在每个结果中完成,例如:obj=results[i].toObject;其中i是循环的索引。
user = user.toObject(); // swap for a plain javascript object instance
delete user["_id"];
delete user["password"];
return callback(null, new SuccessEnvelope(user));