假设我们具有以下架构:
// User
export const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
}
});
export const User = mongoose.model<UserDocument>('User', UserSchema);
// Rates
const UserRateSchema = new mongoose.Schema({
fromUser: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
index : true
},
toUser: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
index : true
},
rate: {
type: Number,
required: true
}
});
export const UserRate = mongoose.model<UserRateDocument>('UserRate', UserRateSchema);
const PostSchema = new mongoose.Schema({
title: {
type: String,
text: true,
required: true
}
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
index: true
}
});
export const Post = mongoose.model<PostDocument>('Post', PostSchema);
现在,我们希望为Post填充用户,因此我们在架构级别定义一个自动填充功能:
const autoPopulate = function (next) {
this.populate('user')
next();
};
PostSchema.pre('find', autoPopulate);
太好了,现在每个帖子都会自动填充用户。
现在,我们希望填充每个用户的平均费率。
例如:
const data = Post.find({});
/*
we want data as bellow :
[{
_id: 'xx',
title: "hello",
user: {
_id: 'xx',
name: 'John',
ratesSummary: {
avg: 1,
count: 2000
}
}
}
]
*/
我尝试使用提到的Here之类的virtual
属性来执行此操作,但是由于未指定localField和foreignField,因此引发了错误。我发现一种有效的方法是:
UserSchema.virtual('rates', {
ref: 'UserRate',
localField: '_id',
foreignField: 'toUser'
});
但是显然,这只会返回UserRates,而不是我们想要的'ratesSummary'...
那么,实现此目标的最佳方法是什么?我想到了虚拟的,但也许不是我想要的东西:/
谢谢!
PS1:由于用户可以有很多费率,因此我们不希望将UserRate ID与User模型一起存储。
PS2:由于许多其他模型都可以附加用户,因此我们不想每次都使用aggregate
来计算user.ratesSummary。