如何在Mongoose中填充虚拟方法中的引用字段?

时间:2012-12-19 10:23:04

标签: node.js mongodb mongoose

我有以下架构。

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是对Place schema的引用,它包含名称,城市,国家等字段。

我想为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 
        }
    }
})

我无法获取this.location.place.name值,因为this.location.place是一个引用,并且未填充。我该如何访问此值?

3 个答案:

答案 0 :(得分:2)

您确定要在查询中调用 .populate()吗?否则,Mongoose将不知道引入引用对象。例如:

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

答案 1 :(得分:1)

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

所以对于你可以使用的选项

{ 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

答案 2 :(得分:1)

我认为没有直接的方法可以做到这一点。实现这一目标的一种方法是遵循钩子。 [Read More]

以下是示例代码。我需要计算由视频组成的教程的总时间。所以,我不得不填充视频,然后使用它们的持续时间来计算教程的总时间。

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;
});