Imagine a user being part of different groups.
A group can have different roles, and a user can be part of different groups.
He also can have different roles in different groups apart from the membership.
The association of a User, a Group and a Role can be referred to as a HyperEdge.
However, it can be easily modeled in a property graph as a node that captures this n-ary relationship, as depicted below in the U1G2R1
node.
Find Groups
To find out in what roles a user is for a particular groups (here Group2), the following query can traverse this HyperEdge node and provide answers.
Query
MATCH ({ name: 'User1' })-[:hasRoleInGroup]->(hyperEdge)-[:hasGroup]->({ name: 'Group2' }), (hyperEdge)-[:hasRole]->(role) RETURN role.name
The role of User1
is returned:
Result
role.name |
---|
1 row |
|
Try this query live create (_0 {`name`:"Group1"}) create (_1 {`name`:"Role"}) create (_2 {`name`:"Group2"}) create (_3 {`name`:"Group"}) create (_4 {`name`:"User1"}) create (_5 {`name`:"U1G2R1"}) create (_6 {`name`:"U1G1R2"}) create (_7 {`name`:"Role2"}) create (_8 {`name`:"Role1"}) create (_0)-[:`isA`]->(_3) create (_0)-[:`canHave`]->(_7) create (_0)-[:`canHave`]->(_8) create (_2)-[:`isA`]->(_3) create (_2)-[:`canHave`]->(_8) create (_2)-[:`canHave`]->(_7) create (_4)-[:`hasRoleInGroup`]->(_6) create (_4)-[:`hasRoleInGroup`]->(_5) create (_4)-[:`in`]->(_2) create (_4)-[:`in`]->(_0) create (_5)-[:`hasGroup`]->(_2) create (_5)-[:`hasRole`]->(_8) create (_6)-[:`hasGroup`]->(_0) create (_6)-[:`hasRole`]->(_7) create (_7)-[:`isA`]->(_1) create (_8)-[:`isA`]->(_1) ; match ({name: 'User1'})-[:hasRoleInGroup]->(hyperEdge)-[:hasGroup]->({name: 'Group2'}), (hyperEdge)-[:hasRole]->(role) return role.name
Find all groups and roles for a user
Here, find all groups and the roles a user has, sorted by the name of the role.
Query
MATCH ({ name: 'User1' })-[:hasRoleInGroup]->(hyperEdge)-[:hasGroup]->(group), (hyperEdge)-[:hasRole]->(role) RETURN role.name, group.name ORDER BY role.name ASC
The groups and roles of User1
are returned:
Result
role.name | group.name |
---|---|
2 rows | |
|
|
|
|
Try this query live create (_0 {`name`:"Group1"}) create (_1 {`name`:"Role"}) create (_2 {`name`:"Group2"}) create (_3 {`name`:"Group"}) create (_4 {`name`:"User1"}) create (_5 {`name`:"U1G2R1"}) create (_6 {`name`:"U1G1R2"}) create (_7 {`name`:"Role2"}) create (_8 {`name`:"Role1"}) create (_0)-[:`isA`]->(_3) create (_0)-[:`canHave`]->(_7) create (_0)-[:`canHave`]->(_8) create (_2)-[:`isA`]->(_3) create (_2)-[:`canHave`]->(_8) create (_2)-[:`canHave`]->(_7) create (_4)-[:`hasRoleInGroup`]->(_6) create (_4)-[:`hasRoleInGroup`]->(_5) create (_4)-[:`in`]->(_2) create (_4)-[:`in`]->(_0) create (_5)-[:`hasGroup`]->(_2) create (_5)-[:`hasRole`]->(_8) create (_6)-[:`hasGroup`]->(_0) create (_6)-[:`hasRole`]->(_7) create (_7)-[:`isA`]->(_1) create (_8)-[:`isA`]->(_1) ; match ({name: 'User1'})-[:hasRoleInGroup]->(hyperEdge)-[:hasGroup]->(group), (hyperEdge)-[:hasRole]->(role) return role.name, group.name order by role.name asc