2016-12-17 59 views
4

我有一種情況,我有一個組文檔類型。我想有一個列表字段,其中包含對組中用戶的引用標識。然而,我需要指出哪些用戶具有管理員權限。我是否應該有兩個列表,一個普通用戶和一個管理員,或者有一個自定義文檔,其中嵌入了一個列表,其中只有參考ID和布爾值?這基本上是多對多的,這兩個文件都有一個參考ID到其他文件的清單。我只是不確定如何包含這個其他值。MongoDB:引用其他文檔並附加其他信息

如果讓我用Python/Mongoengine訪問MongoDB的

回答

2

有在當前的形式建模您的要求的各種方式中的任何差異。我會盡力向你展示一種這樣的方式,並使用$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