Mongoose:只查找并选择虚拟中指定的字段

时间:2014-08-21 10:42:44

标签: node.js mongoose

我在mongoose中有UserSchema架构:

var UserSchema = new Schema({
  name: String,
  username: String,
  email: String,
  role: {type: String, default: 'user'},
  following: [{type: Schema.ObjectId, ref: 'User'}],
  followers: [{type: Schema.ObjectId, ref: 'User'}],
  hashedPassword: String,
  provider: String,
  salt: String,
  facebook: {},
  twitter: {},
  github: {},
  google: {}
});

我创建了一个虚拟profile,它只返回公开个人资料的信息:

UserSchema
  .virtual('profile')
  .get(function() {
    return {
      'username': this.username,
      'name': this.name,
      'role': this.role
    };
  });

我的问题是如何在我发出find请求时仅获取此信息。这是我的代码:

UserSchema.statics = {
  list: function (options, callback) {
    var criteria = options.criteria || {};

    this.find(criteria)
      .select(/* What to put here? */)
      .limit(options.perPage)
      .skip(options.perPage * options.page)
      .exec(callback);
  } 
};

当然,我可以简单地放置usernamenamerole,但在这种情况下,我会重复代码。我可以避免吗?

2 个答案:

答案 0 :(得分:0)

您是否因为profile以外的任何原因使用虚拟find?你的虚拟实际上只是指定了一些字段,没有更多动态,所以如果你只是想在查询中选择字段,我会坚持使用它(.select('username name role'))。如果你想让它可重复使用......只需将字符串作为一个值,你可以通过require注入一个模块。然后,您可以在需要的地方进行更改,并像select(profileFields)一样使用它。

答案 1 :(得分:0)

根据mongooejs文件

  

只有非虚拟属性才能作为查询和字段选择的一部分。

你可以这样做

exports.show = function (req, res, next) {
  var userId = req.params.id;

  User.findById(userId, function (err, user) {
    if (err) {
      return next(err);
    }
    res.json(user.profile);
  });
};

但不是这个

exports.devs = function (req, res, next) {
  User.find({role: 'developer'}, 'developer_profile', function (err, users) {
  if (err) {
    return res.status(500).send(err);
  }
  res.status(200).json(users);
  });
};

您可以在此处阅读更多内容http://mongoosejs.com/docs/guide.html#virtuals