如何在 mongo 中处理多对多的关系



在猫鼬模式中构建多对多模型的最佳方法是什么?

我有两个模型,它们彼此之间具有多对多关系。用户可以属于许多组织,组织可以拥有许多用户。

选项:

  1. 通过引用其他模型来定义每个模型中的关系
  2. 通过引用一个模型中的另一个模型来定义另一个模型中的关系

选项 1

const UserSchema = new Schema({
organiations: { type: Schema.Types.ObjectId, ref: "Organiation" }, // references organisation
})
mongoose.model("User", UserSchema)
const OrganiationSchema = new Schema({
users: { type: Schema.Types.ObjectId, ref: "User" }, // references users
})
mongoose.model("Organiation", OrganiationSchema)

乍一看这似乎是一个好主意,这意味着我可以查询组织模型以获取所有用户,还可以查询用户模型以获取所有相关组织。

唯一的问题是我必须维护 2 个事实来源。如果我创建一个组织,我必须更新用户所属的组织,并且我必须使用组织拥有的用户更新组织。

这让我想到了选项 2,即通过仅在一个模型中定义关系来拥有一个事实来源。

选项 2:

const UserSchema = new Schema({
organiations: { type: Schema.Types.ObjectId, ref: "Organiation" }, // references organistion
})
mongoose.model("User", UserSchema)
const OrganiationSchema = new Schema({}) // no referencces
mongoose.model("Organiation", OrganiationSchema)

这意味着当我创建一个新组织时,我只需要更新用户所属的组织。不存在 2 个来源不同步的风险。但是,这确实意味着在查询数据时,它会使它更加棘手。如果我想获取属于某个组织的所有用户,则必须查询用户文档。这意味着我的组织控制器必须同时了解用户和组织模型,当我开始添加更多关系和模型时,我想要避免的所有这些模块之间会紧密耦合。

您建议如何处理猫鼬架构中的多对多关系?

对此没有固定的解决方案。

如果组织的用户数量比用户拥有的组织多几个数量级,则选项 2 可能是更好的解决方案。

在性能方面,只要对引用的 ID 编制索引,填充引用的数据就大致相同。

话虽如此,您可能仍然会选择选项 1,即使您的组织集合有可能拥有"巨大"数组。特别是如果您想进行简单的计算,例如组织用户的数量或使用"组织的当前用户 ID 到其他集合"。在这种情况下,选项 1 会更好。

但是,如果您选择选项 1,并且您的阵列有可能变得非常大,请考虑存储桶设计模式。基本上,您可以限制嵌套数组的最大长度。如果数组达到其最大长度,则创建另一个包含新添加的 id(或嵌套文档(的文档。将其视为分页。

最新更新