您可以使用猫鼬动态引用。这让您可以同时从多个集合中进行填充。
您只需在架构路径上使用refPath 属性而不是ref:
var schema = mongoose.Schema({
message: { type: String, required: true },
author: {
type: { type: String, enum: ['user','student'] },
data: { type: ObjectId, refPath: 'author.type' }
},{
timestamps: true
});
因此,上面的 refPath 属性意味着 mongoose 将查看对话架构中的 author.type 路径以确定要使用的模型。
因此,在您的查询中,您可以像这样填充对话的作者:
Conversation.find({}).populate('author.data').exec(callback);
您可以在documentation page for population(靠近底部)和this pull request 中找到更多信息。
替代方案:Mongoose 鉴别器
根据您的用户模型和学生模型的相关程度,您还可以使用discriminators 来解决此问题。鉴别器是一种模式继承机制。基本上,它们使您能够在同一个基础 MongoDB 集合之上拥有多个具有重叠模式的模型。
当您使用判别器时,您最终会拥有一个基本架构和判别器架构。例如,您可以将 user 设为您的基本架构,并将 student 设为用户的鉴别器架构:
// Define user schema and model
var userSchema = new mongoose.Schema({ name: String });
var User = mongoose.model('User', userSchema);
// Define student schema and discriminate user schema
var studentSchema = new mongoose.Schema({ level: Number });
var Student = User.discriminator('Student', studentSchema);
现在您的学生模型将继承用户的所有路径(因此它也具有 name 属性)并将文档保存到同一个集合中。因此,它也适用于您的参考和查询:
// This will find all users including students
User.find({}, callback);
// This will also find conversations no matter if the referenced user is a student or not
Conversation.find({ user: someId }, callback);