【问题标题】:Mongoose: reference between models with same schema keysMongoose:具有相同模式键的模型之间的引用
【发布时间】:2019-12-08 21:17:48
【问题描述】:

作为前端开发人员,我想为两个 mongoose 模型创建一些 isomorphic 对象。

假设我有一个用户个人资料:

const profileSchema = new Schema({
  firstName: { type: String },
  lastName: { type: String },

  // example of difference between model schemas
  __user: { type: ObjectId, ref: 'Users' },
}

我想创建一个Contact 列表,其中每个联系人都有一些相同的键:

const contactSchema = new Schema({
  firstName: { type: String },
  lastName: { type: String },

  __profile: {
    type: ObjectId,
    ref: 'Profiles',
    unique: true,
  },

  comment: { type: String }, 
}

注意: Contact 可能是两者:

  • 作为Profile参考
  • 并作为独立记录在 DB / document

===============================

我的问题:以这种方式组织模型是最好的方法,所以

  • 联系人可能是对个人资料的引用
  • 当类似Profile 键,如firstName 将更新时,联系人firstName 也会更新

避免下一个参考

await Contact.findById(SOME_ID).populate('__profile');

// result
{
  firstName: '',
  lastName: '',

  __profile: {
    firstName: 'Chuck',
    lastName: 'Norris',
  }
}

期望的结果 - 保持联系“同构”,例如:

{
  firstName: 'Chuck', // the key value from profile
  lastName: 'Norris', // the key value from profile

  __profile: SOME_PROFILE_ID,
}

这可能吗?

P.S:在我的应用程序中,我使用 refs 并开始使用 discriminators 方法。

【问题讨论】:

    标签: mongodb mongoose mongoose-schema mongoose-populate


    【解决方案1】:

    我会处理这个任务:

    1) 将所有数据放入 1 个集合中(例如 Profile):

    // Profile model
    {
    
      firstName: 'Chuck',
      lastName: 'Norris',
    
      contacts: [{
        type: ObjectId,
        ref: 'Profile',
        unique: true,
      }],
      ...all other properties
    
    }
    

    这样您就可以只存储联系人(例如,当我只想添加一个联系人时)和包含更多信息的个人资料。

    2) 或将使用鉴别器创建基类(例如联系人)并在其上构建 Profile 模型:

    const options = { discriminatorKey: 'userType' };
    
    const Contact = mongoose.model('Contact', new mongoose.Schema({
        firstName: String,
        lastName: String
      },
      options)
    )
    
    const Profile = Contact.discriminator(
      'Profile',
      new mongoose.Schema(
        {
          contacts: [{
            type: ObjectId,
            ref: 'Contact',
            unique: true,
          }],
          comments: []
        },
        options
      )
    );
    

    这样您就可以将联系人和个人资料保存在 1 个集合中,并为个人资料中的联系人提供参考基类 (Contact)

    希望有帮助!

    【讨论】:

      【解决方案2】:

      就我而言,完全使用 Mongoose discriminators 并没有给我带来优势,因为鉴别器让你有机会:

      它们使您能够拥有多个模型与重叠架构 位于同一底层 MongoDB 集合之上。

      因此,通过使用鉴别器方法,我将获得一个集合 的:

      • 个人资料

      还会有userscontact 配置文件的组合。

      ================================

      所以我决定使用两种方法:

      结果:

      // keys which are same for both user Profile and Contact
      const Schema = require('mongoose').Schema;
      const util = require('util');
      
      function BaseProfileSchema(...args) {
        Schema.apply(this, args);
      
        this.add({
          firstName: { type: String },
          lastName: { type: String },
        });
      }
      util.inherits(BaseProfileSchema, Schema);
      
      // user Profile Model
      const profileSchema = new BaseProfileSchema({
        __user: {
          type: String,
          ref: 'users',
          required: true,
          unique: true,
        },
      });
      
      const Profile = mongoose.model('profiles', profileSchema);
      
      // Contact with profile as subdocument
      const contactProfileSchema = new BaseProfileSchema();
      
      const contactSchema = new Schema({
        // Associations
        __refProfile: {
          type: Schema.Types.ObjectId,
          ref: 'profiles',
          index: {
            unique: true,
            sparse: true,
          },
        },
        profile: contactProfileSchema,
      });
      
      const Contact = mongoose.model('contacts', contactSchema);
      

      因此,我拥有带有下一个集合的数据库:

      • 用户
      • 个人资料
      • 联系人

      profilescontacts.profile 都是相同的,因为我正在扩展基本共享架构。

      此外:

      • Contact 内部,我有不同的键用于真实引用的配置文件(__refProfile,其他人无法编辑)和contact.profile
      • profile内部连接只能在联系人自己编辑时才能编辑

      PS:快乐编码?‍??

      【讨论】:

        猜你喜欢
        • 2020-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-26
        • 2015-11-09
        • 2012-02-19
        • 1970-01-01
        相关资源
        最近更新 更多