Burak
Burak

Reputation: 5764

How to populate reference field in virtual method in Mongoose?

I have following schema.

var ItemSchema = new Schema({
name : String
,location: {
    address: { type: String, default:''}, 
    geolocation: {longitude: Number, latitude:Number}, 
    place : {type: Schema.Types.ObjectId, ref:'Place'} 
},
ranking_in_place : Number })

Place is a reference to Place schema which has name, city, country etc. fields.

I want to create a virtual for ranking_summary:

ItemSchema.virtual('ranking_summary').get(function() { 
    if(this.ranking_in_place <= 5){
        if(this.ranking_in_place == 1){
            return "Most popular item" + " in " + this.location.place.name 
        }
    }
})

I cannot get this.location.place.name value because this.location.place is a reference, and not populated. How can I access this value?

Upvotes: 6

Views: 5102

Answers (3)

Piyush Patel
Piyush Patel

Reputation: 1751

I think there is no direct method for doing this. One way you can achieve this is by following the hooks. [Read More]

Here is a sample code. I had a need to calculate the totalTime of tutorial which is made up of videos. So, I had to populate videos and then use their duration to calculate totalTime for a tutorial.

tutorialSchema.pre('findOne', function (next) {
    this.populate('videos');  // now available as this.ratings in this schema
    next();
});

tutorialSchema.virtual('totalTime').get(function () {
    let times = [];
    times = this.videos.map((v) => {
        return v.duration;
    });
    if(times.length === 0) return 0;
    let totalTime = times.reduce((sum, time) => {
        return sum + time;
    });
    return totalTime;
});

Upvotes: 1

Elankeeran
Elankeeran

Reputation: 6184

Model.find().populate(path, fields, conditions, options);

so for options you could use

{ sort: 'order' } // ascending
{ sort: [['order', 1 ]] } // ascending
{ sort: [['order', 'asc' ]] } // ascending
{ sort: [['order', 'desc' ]] } // ascending
{ sort: [['order', -1 ]] } // descending
{ sort: [['order', 'desc' ]] } // descending
{ sort: [['order', 'descending' ]] } // descending

Upvotes: 1

matthewtole
matthewtole

Reputation: 3247

Have you made sure to call .populate() on your queries? Otherwise, Mongoose won't know to pull in the reference object. Example:

ItemModel.findOne().populate('place').exec(function (err, item) {
    console.log(item.ranking_in_place)
})

Upvotes: 2

Related Questions