There are various ways to model your requirement in the current form. I will try to show you one such method and use $ lookup . You should try with two separate collections, one for each group and users, as shown below.
Another option would be to use $ DBRef , which will load all users in the group when you receive the group collection. This option will depend on the python driver, and I'm sure the driver supports this.
Groups document
{
"_id": ObjectId("5857e7d5aceaaa5d2254aea2"),
"name": "newGroup",
"usersId": ["user1", "user2"]
}
User Document
{ "_id" : "user1", "isAdmin" : true }
{ "_id" : "user2" }
Get all users in a group
db.groups.aggregate({
$unwind: '$usersId'
}, {
$lookup: {
from: "users",
localField: "usersId",
foreignField: "_id",
as: "group_users"
}
})
answer
{
"_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
}]
}
:
- admin , . -.
, , -. , , .
{ "_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"
}
})