如何限制find()

时间:2016-03-29 12:18:30

标签: node.js mongoose 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);

但是当我找到数据时,例如

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

    res.json(users);
  });

它总是返回

[
    {
        _id: "56fa6c15a9383e7c0f2e4477",
        username: "abca",
        password: "$2a$05$GkssfHjoZnX8na/QMe79LOwutun1bv2o76gTQsIThnjOTW.sobD/2",
        __v: 0,
        test: "hello world"
    }
]

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

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

});

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

3 个答案:

答案 0 :(得分:1)

  1. 您希望test属性保留在数据库中,并且在查询时不希望它被选中:
  2. 您可以在预查找钩子中使用select

    UserSchema.pre('find', function (next) {
        this.select({ test: false });
        next();
    });
    

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

    此挂钩只会针对find个查询执行,而不会针对findByIdfindOne个查询执行。

    OR

    (参见Hank Chiu的回答)

    在架构中将select标志设置为false:

    test: {
          type: String, 
          default: 'hello world',
          select: false,
    }
    
    1. 您不希望test属性保留在数据库中:
    2. 从架构中删除test属性并添加test虚拟:

      schema.virtual('test').get(function () {
          return 'hello world';
      });
      

      user.test将返回hello world

      1. 您希望测试属性保留在数据库中,但返回不同的内容:
      2. 添加getter您的test定义:

        test: {
            type: String, 
            default: 'hello world',
            get: function () {
                return 'hello guys';
            }
        }
        

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

        错误的答案:

        <击> 您可以使用select将模型属性的对象作为键,将布尔值作为值:

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

        <击>

答案 1 :(得分:1)

将架构设置为

test: {
    type: String, 
    default: 'hello world',
    select: false
}

检查SchemaType#select中的document

答案 2 :(得分:0)

使用select函数作为示例

User.find(/* condition */).select('username -_id -__v')

上面的代码将仅返回username字段

TL:DR

字段被写为带有空格分隔符的单个字符串,以排除字段添加-前缀,例如-_id-username