猫鼬:具有相同模式键的模型之间的引用

Mongoose: reference between models with same schema keys

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

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

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 可能是两者:

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

我的问题:以这种方式组织模型的最佳方式是什么,所以

避免下一个参考[​​=58=]

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

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

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

想要的结果 - 保持联系 "isomorphic" 喜欢:

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

  __profile: SOME_PROFILE_ID,
}

这可能吗?

P.S:在我的应用程序中,我使用了 refs and started to use discriminators 方法。

我会处理这个任务:

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

// Profile model
{

  firstName: 'Chuck',
  lastName: 'Norris',

  contacts: [{
    type: ObjectId,
    ref: 'Profile',
    unique: true,
  }],
  ...all other properties

}

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

2) 或将使用鉴别器创建基础 class(例如联系人)并在其上构建个人资料模型:

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 个集合中保存联系人和个人资料,并在个人资料

中保存联系人的参考库 class (Contact)

希望对您有所帮助!

在我的例子中,完全使用 Mongoose discriminators 并没有给我带来优势,因为鉴别器让你有机会:

They enable you to have multiple models with overlapping schemas on top of the same underlying MongoDB collection.

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

  • 个人资料

而且会有 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内部连接只有在自己编辑联系人时才可以编辑

P.S:编码愉快 ‍