如何在对话中显示两种不同模式之间的关系
问题是我有两个不同的Schema可以代替Conversation
模型中的用户属性,我怎么能代表这个。 它可能是Student
谁messaged或User
发送消息,请注意学生和用户是不同的模型/架构。
var mongoose = require('mongoose'); var schema = mongoose.Schema({ message: { type: String, required: true }, user: { type: ObjectId, ref: 'User' /* I want a Student to also be a ref */ } }, { timestamps: true }); var model = mongoose.model('Conversation', schema); module.exports = { model, schema };
我该如何更好地表示或编写此架构/模型?
你可以使用mongoosedynamic引用 。 这让我们从多个集合中同时填充。
你只需要使用refPath
属性,而不是在schema的path上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
path来确定使用哪个模型。
所以在你的查询中,你可以像这样填充对话的作者:
Conversation.find({}).populate('author.data').exec(callback);
您可以在文档页面上find更多信息(靠近底部),也可以在此拉取请求中查找。
替代scheme:mongoose鉴别器
根据你的用户和学生模型的相关程度,你也可以使用鉴别器来解决这个问题。 鉴别器是一个模式inheritance机制。 基本上,它们使您能够在相同的基础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);
现在,您的学生模型将inheritance用户的所有path(因此它也具有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);