Javascript 如何从文档中排除某些字段

Javascript 如何从文档中排除某些字段,javascript,mongodb,express,mongoose,Javascript,Mongodb,Express,Mongoose,我有以下简单的shema: var userSchema = new Schema({ name : String, age: Number, _creator: Schema.ObjectId }); var User = mongoose.model('User',userSchema); 我想做的是创建新文档并返回到客户端,但我想从其中排除“创建者”字段: app.post('/example.json', function (req, res) {

我有以下简单的shema:

 var userSchema = new Schema({
    name : String,
   age: Number,
   _creator: Schema.ObjectId
  });

  var User = mongoose.model('User',userSchema);
我想做的是创建新文档并返回到客户端,但我想从其中排除“创建者”字段:

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:最好通过

将文档转换为可自由修改的普通JS对象:

user = user.toObject();
delete user._creator;
res.json(200, {user: user});

在模式级别处理此问题的另一种方法是覆盖模型的toJSON

UserSchema.methods.toJSON = function() {
  var obj = this.toObject()
  delete obj.passwordHash
  return obj
}

我遇到了这个问题,想从我提供给客户端的json中排除密码散列,而
select:false
破坏了我的verifyPassword函数,因为它根本没有从数据库检索到值。

当我试图用pymongo找到类似的答案时,遇到了你的问题。事实证明,在MongoShell中,通过find()函数调用,可以传递第二个参数,该参数指定结果文档的外观。当您传递属性值为0的字典时,您将在此查询产生的所有文档中排除此字段

例如,在您的情况下,查询如下所示:

db.user.find({an_attr: a_value}, {_creator: 0});
它将为您排除_creator参数

在pymongo中,find()函数基本相同。不知道它是如何翻译成猫鼬的。我认为这是一个更好的解决方案,而不是事后手动删除字段

希望能有所帮助。

记录的方法是

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;
    }
});

我会使用lodash实用程序或

另一个例子是:

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});
    });
});

我正在使用Mongoosemask,对此非常满意

它确实支持根据需要使用其他名称隐藏和公开属性


var maskedModel=mongomask.mask(model,['name','age'])//你就完了

遵循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}));
在这种情况下,密码将从查询中排除



font:

创建一个没有上述字段的新json对象并返回它。有什么问题吗?@SergioTulentsev太啰嗦了!应该有更好的方法。谢谢您的回答,我可以定义一个永远不会返回架构级别的字段吗?默认情况下,您可以通过在字段定义中包含
select:false
,来隐藏架构字段。这是一种比更改所有对象的默认序列化更好的方法。尽管其他方法可能会起作用,对我来说,这似乎是正确的答案。这在某些情况下可能有效,但不是大多数情况下,因为即使您不想显示字段,也很有可能希望在后端对其进行操作。此解决方案和许多其他类似解决方案的问题在于,从未从数据库中检索到相关字段。如果您有其他依赖它的计算字段或虚拟字段,它们将无法正确设置。目前,绕过Mongoose似乎是Mongoose的推荐做法。让我们怀疑猫鼬是否能胜任这项任务。@nottinhill无关撇号!尝试使用UserSchema.set('toJSON',{transform:function(doc,ret,options){delete ret.password;return ret;}});任何复制此代码的人都要小心,obj前面应该有一个var语句,否则它将泄漏一个全局引用。@sirbenji您没有抓住要点。重点是添加一个toJSON方法,您可以在其中转换输出。
passwordHash
属性本身是不相关的解决方案,而不是创建新对象,并且不设置除passwordHash之外的所有字段。是否有方法将其扩展为条件筛选字段?例如,管理员希望看到一个“approved_by”,但普通客户端不应该看到。或者,如果您已经有下划线/lodash,您可以使用
u.pick
UserSchema.set('toJSON',{transform:function(doc,ret,options){return_u.pick(ret,'email','registed','modified')})@xerri-这在哪里有记录?我明白了,但是找不到transform@xerri-找到了,只是有点困惑,因为文档在toObject not toJSON==>下,在mongoose v4.4.6^中使用findByIdAndUpdate更新时,这不起作用。需要帮忙吗?
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}));