【问题标题】:How to show relationship between two different schemas in a conversation如何在对话中显示两个不同模式之间的关系
【发布时间】:2017-06-18 03:50:13
【问题描述】:

问题是我有两个不同的模式可以代替Conversation 模型中的用户属性,我该如何表示。可能是Student 发消息或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 };

如何更好地表示或编写此架构/模型

【问题讨论】:

    标签: javascript node.js mongodb mongoose database


    【解决方案1】:

    您可以使用猫鼬动态引用。这让您可以同时从多个集合中进行填充。

    您只需在架构路径上使用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);
    

    【讨论】:

    • @seyi-adekoya 是否有一个选项为您解决了问题?
    • 那么如何使用 refPath 解决方案创建一个学生类型的新用户
    • 您可以像使用 .create() 的任何其他模型一样创建它,例如User.create() 或 Student.create() 然后您将集合中的类型设置为“用户”或“学生”并简单地在数据字段中设置 id:Collection.create({author: { type:'学生',数据:'5889d7971442b111ec1a93e8' }});
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    相关资源
    最近更新 更多