首页 > 解决方案 > 如何在没有任何缺点的情况下在 MongoDB 中正确地建立一对一的关系?

问题描述

我正在做一个项目,有这两个 MongoDB 集合,团队(持有团队的详细信息)和付款(持有团队的付款)(严格 1-1 关系)。

Payment Schema
{
    ...
    team: { type: Schema.Types.ObjectId, ref: 'Team', unique: true },
    ...
}

对于团队,我有两种选择:

Team1 Schema
{
    user_id: { type: Schema.Types.ObjectId, ref: 'User' }
}

...

Team2 Schema
{
    user_id: { type: Schema.Types.ObjectId, ref: 'User' }
    payment: { type: Schema.Types.ObjectId, ref: 'Payment', unique: true }
}

需要:我有一个组件“我的团队”,我需要在其中显示登录用户的所有团队及其付款状态(是/否)。

Team1 Schema 的问题:由于我没有对 Payment 的引用,因此我需要使用团队的 _id 再次调用后端以获取每个团队的 Payment 对象。如果用户有 10 个团队,那么它将是 11 个后端调用(1 个用于团队,接下来 10 个用于支付状态)。

Team2 Schema 的问题:由于我现在在 Team2 Schema 中有 Payment_id,所以我可以简单地检查该字段是否存在以确定它是否已付款。但现在的问题是,当付款时,我需要更新两个集合并需要使用事务(在任何失败的情况下回滚),这会增加复杂性并且除非我设置了副本集,否则也不支持。

你能帮我找出最好的方法吗?

提前致谢。

标签: node.jsdatabasemongodbmongoose

解决方案


最简单的解决方案就是在支付模式中包含 team_id(您已经拥有)。

您既不需要 user_id 也不需要在 team 模式中使用 payment_id 来获得团队的付款。您可以只在支付表上查找聚合查询,以使团队获得付款。

因此,考虑到您有一个团队 ID,并且您需要团队数据和付款数据,您可以编写一个聚合查询,如下所示,

             Team.aggregate([
            {
                $match: { _id: { $in: list_of_user_ids } } // this will get the teams which match the array of ids
            },
            {
                $lookup: // this will search data from a different collection
                {
                    from: 'payments', // the collection to search from
                    localField: '_id', // the matching field in the team collection
                    foreignField: 'team', // matching field in the payment colection
                    as: 'payment' the name you want to give to the resulting payment object
                }
            }
           ])

编辑 1: 我写的查找完全符合您的需要。只是我假设您有一组用户 ID。如果您只有一个用户 ID,只需将匹配操作更改为您编写的内容

           $match: { user_id:  currently_loggedin_userId } 

推荐阅读