13

I have a query like this:

galleryModel.find({_id: galleryId})
            .populate({
                model: 'User',
                path: 'objectId',
                select: 'firstName lastName'
            })

End response for objectId will be like this:

objectId: {
...
}

How can I change it to user in response without changing real path?

chridam
  • 100,957
  • 23
  • 236
  • 235
Vladimir Djukic
  • 925
  • 2
  • 9
  • 28

1 Answers1

7

You can do this by virtual populate, introduced in mongoose version 4.5 . For that you need to define a virtual field in mongoose schema.

var GallerySchema = new mongoose.Schema({
    name: String,
    objectId: {
        type: mongoose.Schema.Types.ObjectId
    },
});

GallerySchema.virtual('user', {
    ref: 'User',
    localField: 'objectId', 
    foreignField: '_id' 
});

Ans when you run find query, just populate it with user.

Gallry.find({_id: galleryId}).populate('user','firstName lastName').exec(function(error, gallery) {
    console.log(error);
    console.log(gallery);;
});

Above code is not tested in program, there may be typos, You can get more details about mongoose virtual populate on below link

http://mongoosejs.com/docs/populate.html

Puneet Singh
  • 3,477
  • 1
  • 26
  • 39
  • This works, but I needed to execute the populate separated from the query using `data = await Model.findOne({...})`and `data.populate("name", {key: 1}).execPopulate()`, and as you can see I'm not using a string to define the attributes that are gonna be retrieved / async await –  Jun 21 '20 at 22:17
  • 1
    Also don't forget to add `toJSON: { virtuals: true }` in your schema options object, otherwise, the virtuals won't get sent in the JSON response of a API http request. – Brunno Vodola Martins Apr 24 '23 at 15:15