如何限制在find()期间不存在于数据库中的猫鼬默认值

waq*_*mil 5 mongoose node.js mongoose-schema

我有以下架构。

var UserSchema = new mongoose.Schema({
  username: {
    type: String,
    unique: true,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  test: {
    type: String, 
    default: 'hello world'
  }
});

UserSchema.pre('save', function(callback) {
  var user = this;
  this.test = undefined; // here unset test field which prevent to add in db 
});

module.exports = mongoose.model('User', UserSchema);
Run Code Online (Sandbox Code Playgroud)

但是当我找到数据时

User.find(function(err, users) {
    if (err)
      res.send(err);

    res.json(users);
  });
Run Code Online (Sandbox Code Playgroud)

它总是返回

[
    {
        _id: "56fa6c15a9383e7c0f2e4477",
        username: "abca",
        password: "$2a$05$GkssfHjoZnX8na/QMe79LOwutun1bv2o76gTQsIThnjOTW.sobD/2",
        __v: 0,
        test: "hello world"
    }
]
Run Code Online (Sandbox Code Playgroud)

我如何修改或添加任何特殊参数来获取没有test字段且查询没有任何更改的数据,让我们说

User.find({}, '-test', function (err, users){

});
Run Code Online (Sandbox Code Playgroud)

另外,我在模型中设置了默认值:test: "hello world" 但我不希望这个值出现在响应中。我也设置了this.test = undefined;,这应该意味着它阻止将此默认值添加到数据库中,但是我仍然收到此响应。

Kom*_*omo 2

  1. 您希望该test属性保留在数据库中,只是不希望在查询时选择它:

您可以select在预查找挂钩中使用:

UserSchema.pre('find', function (next) {
    this.select({ test: false });
    next();
});
Run Code Online (Sandbox Code Playgroud)

在查询挂钩(例如,与保存挂钩相对)中,this引用您的查询对象。在保存挂钩中,它指的是当前正在保存的文档。

find该钩子仅针对查询执行,而不针对findByIdfindOne查询执行。

或者

(见Hank Chiu的回答)

在模式中将选择标志设置为 false :

test: {
      type: String, 
      default: 'hello world',
      select: false,
}
Run Code Online (Sandbox Code Playgroud)
  1. 您不希望该test属性保留在数据库中:

从架构中删除该test属性并添加一个testvirtual :

schema.virtual('test').get(function () {
    return 'hello world';
});
Run Code Online (Sandbox Code Playgroud)

user.test将返回hello world

  1. 您希望测试属性保留在数据库中但返回不同的内容:

添加getter您的test定义:

test: {
    type: String, 
    default: 'hello world',
    get: function () {
        return 'hello guys';
    }
}
Run Code Online (Sandbox Code Playgroud)

user.test将返回hello guys,但其真实值将保留在数据库中。

旧的错误答案:

您可以使用select它将模型属性的对象作为键和布尔值作为值:

User
    .find({})
    .select({
        test: false;
    })
    .exec(function (err, users) {
        // users won't have the test property
    });
Run Code Online (Sandbox Code Playgroud)

  • 这与“-test”的作用完全相同。所以这不是OP所要求的。他们希望“自动”排除该字段,以便**每个** `.find()` 调用都已经排除了该字段,而不必执行 `'-test'` 或 `.select({ "test": false })`或 `.select({ "test": -1 })` (这又是同一件事) (2认同)