我知道在文档数据库中不可能或不赞成JOIN。我来自关系数据库背景,并试图了解如何处理这种情况。
假设我有一个Employees集合,我存储了所有与员工相关的信息。以下是典型的员工文档:
{
"id": 1234,
"firstName": "John",
"lastName": "Smith",
"gender": "Male",
"dateOfBirth": "3/21/1967",
"emailAddresses":[
{ "email": "johnsmith@mydomain.com", "isPrimary": "true" },
{ "email": "jsmith@someotherdomain.com", "isPrimary": "false" }
]
}
我们还要说,我有一个单独的项目集合,我存储的项目数据看起来像这样:
{
"id": 444,
"projectName": "My Construction Project",
"projectType": "Construction",
"projectTeam":[
{ "_id": 2345, "position": "Engineer" },
{ "_id": 1234, "position": "Project Manager" }
]
}
如果我想要返回项目团队的所有项目列表,我该如何处理以确保我返回有关团队中个人的所有相关信息,即全名,电子邮件地址等?
是两个单独的查询吗?一个用于项目,另一个用于ID出现在项目集合中的人员?
如果是这样,我如何插入有关人员的数据,即全名,电子邮件地址?然后我在我的应用程序中执行foreach循环来更新数据吗?
如果我依赖我的应用程序来处理所有相关数据的填充,那么这不是会影响MongoDB等文档数据库的性能优势吗?
感谢您的帮助。
答案 0 :(得分:7)
" ...我如何处理以确保我返回有关团队中个人的所有相关信息,即全名,电子邮件地址等?这是两个单独的查询吗?"
它是2个单独的查询,或者您在项目文档中反规范化。在我们的应用程序中,我们进行第二次查询,并在文档中尽可能将数据标准化。
看到" _id"实际上并不常见。键在任何地方,但在顶级文档上。此外,对于您将拥有数百万个文档的集合,您可以通过保留密钥来节省存储空间"简洁"。考虑" name"而不是" projectName"," type"而不是" projectType"," pos"而不是"位置"。它似乎微不足道,但它加起来。您还希望在" team.empId"上添加索引。所以查询" Joe Average工作了多少个项目"运行良好。
{
"_id": 444,
"name": "My Construction Project",
"type": "Construction",
"team":[
{ "empId": 2345, "pos": "Engineer" },
{ "empId": 1234, "pos": "Project Manager" }
]
}
另一件需要习惯的事情是,每次要更新单个字段时,您都不必编写整个文档,或者说,向团队添加新成员。您可以执行唯一标识文档的目标更新,但只更新单个字段或数组元素。
db.projects.update(
{ _id : 444 },
{ $addToSet : "team" : { "empId": 666, "position": "Minion" } }
);
首先要完成一件事的2个查询会受到伤害,但是你会超越它。
答案 1 :(得分:0)
Mongo DB是一个文档存储数据库。 它支持高可用性和可伸缩性。
要返回所有项目的列表以及项目团队(详细信息), 根据我的理解,你将不得不运行2个查询。 由于mongoDb没有FK约束,我们需要在程序级别维护它。 而不是FK约束, 1)如果数据较少,那么我们可以将数据作为子文档嵌入。 2)而不是规范化设计db的方式,在MongoDb中我们需要根据访问模式进行设计。即我们更有可能查询数据的方式。 (但是更新的时间更多(慢),但在用户端,性能主要取决于读取活动,这将比RDBMS更好)
以下链接提供免费的mongo Db证书课程。 Mongo DB University 他们还有一个论坛,非常好。