66

我有以下简单的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
} 

是否可以在没有额外查找请求的情况下制作猫鼬?

PS:最好是通过

4

8 回答 8

80

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

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

我遇到了这个问题,寻找一种从我提供给客户端的 json 中排除密码哈希的方法,并select: false破坏了我的 verifyPassword 函数,因为它根本没有从数据库中检索值。

于 2012-06-23T06:41:59.000 回答
62

记录的方式是

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;
    }
});
于 2013-06-12T10:49:37.537 回答
18

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

例如,在您的情况下,查询将类似于:

db.user.find({an_attr: a_value}, {_creator: 0});

它将为您排除 _creator 参数。

在 pymongo 中,find() 函数几乎相同。不知道它是如何转化为猫鼬的。与事后手动删除字段相比,我认为这是一个更好的解决方案。

希望能帮助到你。

于 2012-11-18T05:39:34.327 回答
15

我会使用 lodash 实用程序.pick()。忽略()

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});
    });
});
于 2014-08-06T04:29:29.363 回答
14

您可以调用toObject()文档将其转换为可以自由修改的纯 JS 对象:

user = user.toObject();
delete user._creator;
res.json(200, {user: user});
于 2012-06-22T17:16:35.073 回答
9

通过遵循 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}));

在这种情况下,密码将从查询中排除。

字体:https ://docs.mongodb.com/v2.8/tutorial/project-fields-from-query-results/#return-all-but-the-excluded-field

于 2017-11-22T10:46:19.750 回答
1

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

它确实支持根据您的需要隐藏和公开具有其他名称的属性

https://github.com/mccormicka/mongoosemask

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

于 2014-08-26T19:06:01.423 回答
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),
  });
于 2021-06-23T18:30:15.517 回答