没有JOIN,处理文档数据库中数据的正确方法是什么?

Sam*_*Sam 6 sql document mongodb mongodb-query azure-cosmosdb

我知道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" }
   ]
}
Run Code Online (Sandbox Code Playgroud)

我们还说,我有一个单独的项目集合,我存储的项目数据看起来像这样:

{
   "id": 444,
   "projectName": "My Construction Project",
   "projectType": "Construction",
   "projectTeam":[
      { "_id": 2345, "position": "Engineer" },
      { "_id": 1234, "position": "Project Manager" }
   ]
}
Run Code Online (Sandbox Code Playgroud)

如果我想返回我的所有项目列表以及项目团队,我该如何处理以确保我返回有关团队中个人的所有相关信息,即全名,电子邮件地址等?

这是两个单独的查询吗?一个用于项目,另一个用于ID出现在项目集合中的人员?

如果是这样,我如何插入有关人员的数据,即全名,电子邮件地址?然后我在我的应用程序中执行foreach循环来更新数据吗?

如果我依赖我的应用程序来处理所有相关数据的填充,那么这不是一个性能损失会抵消MongoDB等文档数据库的性能优势吗?

谢谢你的帮助.

Bob*_*har 7

"...我如何处理以确保我返回有关团队中个人的所有相关信息,即全名,电子邮件地址等?这是两个单独的查询吗?"

它可以是2个单独的查询,也可以在项目文档中进行非规范化.在我们的应用程序中,我们进行第二次查询,并在文档中尽可能标准化数据.

在顶层文档中的任何地方都可以看到"_id"键并不常见.此外,对于您将拥有数百万个文档的集合,您可以通过保持密钥"简洁"来节省存储空间.考虑"名称"而不是"projectName","type"而不是"projectType","pos"而不是"position".它似乎微不足道,但它加起来.你还想在"team.empId"上放一个索引,这样查询"Joe Average工作了多少个项目"运行良好.

{
  "_id": 444,
  "name": "My Construction Project",
  "type": "Construction",
  "team":[
    { "empId": 2345, "pos": "Engineer" },
    { "empId": 1234, "pos": "Project Manager" }
  ]
}
Run Code Online (Sandbox Code Playgroud)

另一件需要习惯的事情是,每次要更新单个字段时,您都不必编写整个文档,或者向团队添加新成员.您可以执行唯一标识文档的目标更新,但只更新单个字段或数组元素.

db.projects.update(
  { _id : 444 },
  { $addToSet : "team" : { "empId": 666, "position": "Minion" } }
);
Run Code Online (Sandbox Code Playgroud)

完成一件事情的2个问题一开始就会受到伤害,但你会超越它.