首页 > 解决方案 > MongoDB中的三级关系

问题描述

我有三级关系数据库,第一张表user例如我有user A,B。每个user都有expense type例如食物,租金费用。最后各有各expense type的费用。

现在的结构是这样的:user ==> expense_type ==> expense.

如果我在MYSQL中设计这个数据库,我会创建三个不同的表并在它们之间创建关系,我可以很容易地找到 每个用户的所有费用。

//mysql query to return all expenses for user A
select 
    expense.* 
from 
    user, expense, expense_type 
where 
    user.id=expense_type.user_id and 
    expense.type_id=expense_type.id and 
    user.id=1 //id of user A

但我的问题是,我必须使用Mongodb(我使用 Mongoose 和 Express) ,现在我的问题是在Mongodb中设计这个数据库的最佳实践是什么?我怎样才能全部expenses退回user

我会感谢任何帮助:)

标签: mongodbmongoose

解决方案


这是您可以使用的一种方法。每个用户的所有费用都与用户一起存储,如示例文档中所示。用户的费用存储在一个数组中,每个数组元素是一个费用子文档(带有费用类型和金额)。这样,您将只需要数据模型中的一个集合。

集合中的示例文档user_expenses(假设_id与用户 ID 相同):

{
        "_id" : 1,
        "exp" : [
                {
                        "exp_type" : "food",
                        "amt" : 25
                },
                {
                        "exp_type" : "rent",
                        "amt" : 500
                }
        ]
},
{
        "_id" : 2,
        "exp" : [
                {
                        "exp_type" : "food",
                        "amt" : 18
                },
                {
                        "exp_type" : "gas",
                        "amt" : 48
                },
                {
                        "exp_type" : "misc",
                        "amt" : 33
                }
        ]
}


查询:

我们如何查询这个集合?以下是一些示例用例。

(1) 如何退还任何用户的所有费用?

db.user_exp.find( {_id: 1 } )

输出:

{ "_id" : 1, "exp" : [ { "exp_type" : "food", "amt" : 25 }, { "exp_type" : "rent", "amt" : 500 } ] }


(2) 如何获取用户所有费用的总和?

db.user_exp.aggregate( [
    { $match: { _id: 1 } },
    { $unwind: "$exp" },
    { $group: { _id: "$_id", "sum_exp": { $sum: "$exp.amt" } } }
] )

输出:

{ "_id" : 1, "sum_exp" : 525 }


(3) 查询用户的具体费用类型:

db.user_exp.aggregate( [
    { $match: { _id: 2 } },
    { $unwind: "$exp" },
    { $match: { $or: [ { "exp.exp_type": { $eq: "food" } }, {"exp.exp_type": { $eq: "misc" } } ] } }
] )

输出:

{ "_id" : 2, "exp" : { "exp_type" : "food", "amt" : 18 } }
{ "_id" : 2, "exp" : { "exp_type" : "misc", "amt" : 33 } }



数据建模:

MongoDB 的灵活模式允许根据用例或应用程序需求设计数据(它不像关系数据库 (SQL) 中的方法,您必须使用相当严格的方法)。

要了解有关数据库设计(或数据建模)的更多信息,请参阅数据建模介绍中的 MongoDB 文档。


推荐阅读