Reputation: 103
On a new project I've decided to go with mongodb for the main database, but my inexperience with it has led to some confusion in how I should structure the relationships between different collections.
In my case I have a users collection, a 'notes' collection and a groups collection. Notes can be open to different users and groups. If a user is part of a group and that group has read access to the note, then so does the user. If the user is removed from the group, then they no longer have access to the note. However, a user may have access to the note on a user basis, and even if they are removed from a group with access, they can still see the note. Hopefully that makes sense.
The problem I'm facing is setting up the permissions so that all of this is possible. Should the permissions be stored in the notes collection? If its stored as follows:
note: {id: xxxx, followers:[{id:user1, permission:write},{id:groupA, permission:read}]}
Then in the case that a user2 is part of groupA, I would need to check to see if they are associated with the node by their id, and if not, I will have to check each group that can see that note and look at their members, and if different groups have different permissions, I have to take the highest permission. This doesn't seem efficient.
The users collection looks like this:
user: {id:user1, projects:[xxxxx, xxxxx], groups:[xxxxx,xxxx...]}
The groups collection:
group: {id:groupA, projects:[xxxxx, xxxx...], users:[user2...]}
I was planning on linking the group documents with the project and user documents so that if the group is removed from a project, the project would be removed from the group. It seems like a dbref is the best way to do this.
I've looked through best practices and I feel like the overall structure I have is messy, but I can't think of another way to do it.
Upvotes: 0
Views: 453
Reputation: 30136
Given your requirements, if groups have more users than users have groups then you should consider storing group_ids within a user.
You could combine users and groups into one collection that had two different schemas and something like an is_group attribute but conceivably there could one day be collection level locking and the below would give you more flexibility.
To figure out if a user has access you would only need to query the project collection and see whether the group ids they are members of are within the write or read arrays after the project document is retrieved.
Project:
{
"_id": ObjectId,
"write": [group_id, group_id, ...],
"read": [group_id, group_id, ...]
}
User:
{
"_id": ObjectId,
"groups": []
}
Group:
{
"_id": ObjectId,
}
Upvotes: 1