MongoDB:引用其他文档并附加其他信息

问题描述:

我有一种情况,我有一个组文档类型。我想有一个列表字段,其中包含对组中用户的引用标识。然而,我需要指出哪些用户具有管理员权限。我是否应该有两个列表,一个普通用户和一个管理员,或者有一个自定义文档,其中嵌入了一个列表,其中只有参考ID和布尔值?这基本上是多对多的,这两个文件都有一个参考ID到其他文件的清单。我只是不确定如何包含这个其他值。MongoDB:引用其他文档并附加其他信息

如果让我用Python/Mongoengine访问MongoDB的

有在当前的形式建模您的要求的各种方式中的任何差异。我会尽力向你展示一种这样的方式,并使用$lookup。您应该为每个组和用户尝试两个单独的集合,如下所示。其他

一种选择将是使用$DBRef将急切地装载组中的所有用户,当您获取群组集合。这个选项将取决于python驱动程序,我相信驱动程序支持。

组的文档

{ 
    "_id": ObjectId("5857e7d5aceaaa5d2254aea2"), 
    "name": "newGroup", 
    "usersId": ["user1", "user2"] 
} 

用户文档

{ "_id" : "user1", "isAdmin" : true } 
{ "_id" : "user2" } 

获取用户的组

db.groups.aggregate({ 
    $unwind: '$usersId' 
}, { 
    $lookup: { 
     from: "users", 
     localField: "usersId", 
     foreignField: "_id", 
     as: "group_users" 
    } 
}) 

响应

{ 
    "_id": ObjectId("5857e7d5aceaaa5d2254aea2"), 
    "name": "newGroup", 
    "usersId": "user1", 
    "group_users": [{ 
     "_id": "user1", 
     "isAdmin": true 
    }] 
} { 
    "_id": ObjectId("5857e7d5aceaaa5d2254aea2"), 
    "name": "newGroup", 
    "usersId": "user2", 
    "group_users": [{ 
     "_id": "user2" 
    }] 
} 

获取全部Admin用户组中的

db.groups.aggregate({ 
    $unwind: '$usersId' 
}, { 
    $lookup: { 
     from: "users", 
     localField: "usersId", 
     foreignField: "_id", 
     as: "group_users" 
    } 
}, { 
    $match: { 
     "group_users.isAdmin": { 
      $exists: true 
     } 
    } 
}) 

响应

{ 
    "_id": ObjectId("5857e7d5aceaaa5d2254aea2"), 
    "name": "newGroup", 
    "usersId": "user1", 
    "group_users": [{ 
     "_id": "user1", 
     "isAdmin": true 
    }] 
} 

基于评论:

管理员是管理员组,因此我无法将其存储在用户 表中。这是一个多对多的关系。

我想你应该包括常规用户列表和管理员用户列表。这将使用您添加的索引,并且会使您的阅读查询变得非常简单。

组的文档

{ "_id" : "newGroup", "userIds" : [ "user1" ], "adminIds" : [ "user2" ] } 

用户文档

{ "_id" : "user1", "groupIds" : [ "newGroup" ] } -- regular user in newGroup 
{ "_id" : "user2", "groupIds" : [ "newGroup" ] } -- admin user in newGroup. 
{ "_id" : "user3", "groupIds" : [ ] } 

获取所有的常规用户

db.groups.aggregate({ 
    $unwind: '$userIds' 
}, { 
    $lookup: { 
     from: "users", 
     localField: "userIds", 
     foreignField: "_id", 
     as: "group_users" 
    } 
}) 

获取全部Admin用户

db.groups.aggregate({ 
    $unwind: '$adminIds' 
}, { 
    $lookup: { 
     from: "users", 
     localField: "adminIds", 
     foreignField: "_id", 
     as: "group_users" 
    } 
}) 
+0

的是admin是群管理员,所以我不能把它存储在用户表。这是一个多对多的关系。 – Jhorra

+0

这里有几个问题。多对多意味着用户知道他是哪个组的一部分,这意味着您将在每个用户文档中拥有一个组列表?其他问题你如何选择一个用户作为管理员?当你创建一个组时,你为每个组分配一些用户作为管理员吗?根据此评论更新答案。 – Veeram

+0

所以这个应用程序有不同的位置。用户可以访问他们所连接的位置。每个位置的管理员都有权编辑该位置。用户可以连接到许多组,并且一个组有许多用户。每个组的一些用户将是管理员。所以在其他许多我见过的用户中,使用了组中的用户列表和每个用户的组列表。我需要这样做,但也表明你是否也是管理员。 – Jhorra