简体   繁体   中英

Mongoose populate a single virtual field

I have the following schema (CoffeeScript):

adSchema = new mongoose.Schema({
  ...
  user : { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
  ...
},
{
  toObject: { virtuals: true },
  toJSON: { virtuals: true }
})

userSchema = new mongoose.Schema({
  username : String
  email :
    type : String
    required : true
    index :
      unique : true
  adverts : [{ type: mongoose.Schema.Types.ObjectId, ref: 'Advert' }]
},
{
  toObject: { virtuals: true }
  toJSON: { virtuals: true }
})

userSchema.virtual('screenname').get () ->
  if this.username? then this.username else this.email.split('@')[0]+'@...'

Then I try to get a bunch of records and populate the user:

getAdvertPage = (obj, fn) ->
  page_size = 10
  query =
    tags : obj.tag
  Advert.count query, (err, count) ->
    Advert.find(query)
    .sort(obj.sort)
    .skip((obj.page-1)*page_size)
    .limit(page_size)
    .populate('user', 'screenname')
    .exec (err, ads) ->
      ads.lastPage = (obj.page-1)*page_size + page_size >= count
      fn err, ads

But I only want the user's screenname and nothing else (which is a virtual field). However, this results in an error:

Cannot call method 'split' of undefined

If I include the email in the populate it works fine, but I don't want to send the email to the client. Is there no way to populate only a virtual field?

Since you have dependancies on the fields 'email' and 'username' inside the virtual getter for 'screenname', try populating screenname, email and username.

...
.populate('user', 'screenname, email, username')
...

By the way, you should not implement business logic inside virtual getters to avoid situations like this. consider creating another virtual.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM