0

我刚刚涉足 mongoDB 开发。使用 shell,我可以将以下内容存储到一个名为 vrm 的集合中:

w = {
  westpalm :{
    users : [
      {pkanane : {names : {lastName : "Anane", otherNames : "Papa Kwame"}}, contacts : {}, authorization : {}},
      {csquire : {}},
      {oman : {}}
    ],
    customers : [], 
    vehicles : [], 
    settings : []

  }  
}

a = {
  wuduwudu :{
    users : [
      {pkanane : {names : {lastName : "Anane", otherNames : "Papa Kwame"}}, contacts : {}, authorization : {}},
      {zkenpachi : {}}
    ],
    customers : [], 
    vehicles : [], 
    settings : []

  }  
}

然后我保存如下 db.vrm.save(a) 和 db.vrm.save(w)

Q1。我要建模的是2家公司wuduwuduwestpalm,每个公司都有用户客户车辆等。每个用户都有一个名称- 由lastNameotherNames联系人等组成。这是对数据需求建模的好方法吗?

Q2。如何检索用户pkanane的otherNames

谢谢

4

1 回答 1

2

我将首先在您的原始模式的上下文中解决您的第二个问题。使用用户名作为索引将使查询变得更加困难,因为您将有一个变量字段名称可供使用。同样,在用户对象中对此类字段进行索引也不会扩展,因为每个不同的字段路径都需要自己的索引。也就是说,查询效率低下是可能的:

db.companies.drop()
db.companies.insert({
    _id: "wuduwudu",
    users: [
        { pkanane: { fullName: "Papa Kwame" } }
    ]
});
db.companies.find({ "users.pkanane": { $exists: true }}, { "users.pkanane.fullName": 1 });
{ "_id" : "wuduwudu", "users" : [ { "pkanane" : { "fullName" : "Papa Kwame" } } ] }

一种改进是制作users一组嵌入式用户对象。使用此模式,您可以利用字段上的多键索引users.username,Mongo 将为每个文档的数组中的所有用户名编制索引。

db.companies.drop()
db.companies.insert({
    _id: "westpalm",
    users: [
        { username: "pkanane", fullName: "Papa Kwame" }
    ]
});
db.companies.find({ "users.username": "pkanane" }, { "users.pkanane.fullName": 1 });
{ "_id" : "wuduwudu", "users" : [ { "pkanane" : { "fullName" : "Papa Kwame" } } ] });

为了重新考虑您的架构,我将从查看公司和用户对象结构开始。正如我上面提到的,动态字段名称不适用于索引。我建议不要将公司名称用作文档中唯一的顶级键。您可以将它用于_id,就像我在上面的示例中所做的那样,或者依靠 MongoDB 生成 ObjectId 并将公司名称存储在其自己的字段中,旁边是users,customers等。

一般来说,用户是大多数应用程序中的第一类对象。如果您在公司范围之外使用和编辑它们,我会考虑将它们存储在他们自己的集合中,而不是在您的公司文档中保留一组用户 ID。此外,在您自己的示例中,您在两家公司之间复制了“pkanane”。这是另一种气味,您最好在自己的集合中引用用户文档。客户、车辆和设置可能不是应用程序中的一流对象,因此嵌入它们可能更合适。MongoDB 文档中的Schema Design条目是一个很好的起点(我已链接到最佳实践列表)。

嵌入文档的另一个挑战可能是要求您的应用程序允许单独编辑单个嵌入文档。这对于在用户文档中嵌入地址簿并提供“编辑您的地址”表单的架构来说是典型的。使用可以更改的对象的数组位置是不可靠的,因为对象上有一个不可变的字段。使用上面我的第二个代码示例中的模式,username如果它是不可变的,我们可以使用它。或者,我们可以在每个嵌入式文档上存储一个唯一的 ObjectId 并引用它。

最后一点,您最终可能会将用户转移到他们自己的收藏中,但该建议对于您留在公司中的任何内容都是有效的。

于 2012-08-08T19:57:09.410 回答