【发布时间】:2020-10-09 21:43:34
【问题描述】:
在猫鼬模式中构建多对多模型的最佳方法是什么?
我有两个模型,它们之间存在多对多关系。用户可以属于多个组织,组织可以有多个用户。
选项:
- 通过引用另一个模型来定义每个模型中的关系
- 通过引用另一个模型来定义一个模型中的关系
选项 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)
这意味着当我创建一个新组织时,我只需要将用户更新为他们所属的组织。没有两个来源不同步的风险。但是,这确实意味着在查询数据时,它会变得更加棘手。如果我想获取属于某个组织的所有用户,我必须查询用户文档。这意味着我的组织控制器必须了解用户和组织模型,并且当我开始添加更多关系和模型时,我会在所有这些我想要避免的模块之间获得紧密耦合。
您建议如何在猫鼬模式中处理多对多关系?
【问题讨论】:
-
您对选项的看法是正确的,不要忘记选项 1 可能会导致大型组织的用户列表中有很多用户。您可以在这两种策略之间做出选择。
-
您说得对,大型组织可能有很多用户。但这也可能是选项 2 的问题。如果我试图在他们的组织数组中找到所有具有 organization._id 的用户,那么这不是很优雅。不确定猫鼬如何处理这个问题,但可能是一个潜在的性能问题。
-
如果您真的关心性能,则需要优先考虑要求(查询时间/存储空间/查询灵活性)并将您的架构调整到这些要求。
-
当您提到拥有大量用户的组织时,我不确定我是否理解您在暗示什么。这如何只影响选项 1 而不会影响选项 2?
-
如果您有一个拥有 10000 个用户的组织,则每个用户在 organizations 数组中都有一个组织,但该组织在其 users 数组中具有 10000 个用户。用户属于 10000 个组织的可能性较小。
标签: javascript mongodb mongoose nosql many-to-many