mongodb - 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
?
我会感谢任何帮助:)
解决方案
这是您可以使用的一种方法。每个用户的所有费用都与用户一起存储,如示例文档中所示。用户的费用存储在一个数组中,每个数组元素是一个费用子文档(带有费用类型和金额)。这样,您将只需要数据模型中的一个集合。
集合中的示例文档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 文档。
推荐阅读
- javascript - 在 Postman 中发送带有文本正文的请求
- orleans - 在奥尔良创建同名的流和谷物
- ios - 有人可以从 iOS 应用程序的 IPA 文件中访问我的源代码吗?
- gitlab - gitlab ci 试图连接回 git
- node.js - chalk.green.bold("Some Text") 和 chalk.bold.green("Some Text") 如何在 npm 包 chalk 的后台进行编码
- python-3.x - 字符串与文件内容比较期间的奇怪行为
- java - 尝试点击 url 时出现 Google Cloud Spring-Boot 404 错误
- sql - 加入三个 CTE - 我正在尝试在 3 个 CTE 之间加入( cte_1.InvoiceDate11=cte_2.InvoiceDate11=cte_3.EndDate11 )。你能帮我吗?
- jackson - 在 Jackson 中将具有 Double 值的字符串转换为 Long 数据类型
- docker - Docker 以守护程序模式退出