5.1. Hyperedges and Cypher

5.1.1. Find Groups
5.1.2. Find all groups and roles for a user
5.1.3. Find common groups based on shared roles

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.

Graph

cypher-hyperedge-graph.svg

5.1.1. Find Groups

To find out in what roles a user is for a particular groups (here Group2), the following Cypher Query can traverse this HyperEdge node and provide answers.

Query

START n=node:node_auto_index(name = "User1")
MATCH n-[:hasRoleInGroup]->hyperEdge-[:hasGroup]->group, hyperEdge-[:hasRole]->role
WHERE group.name = "Group2"
RETURN role.name

The role of User1:

Result

role.name
1 row, 1 ms

"Role1"


5.1.2. Find all groups and roles for a user

Here, find all groups and the roles a user has, sorted by the roles names.

Query

START n=node:node_auto_index(name = "User1")
MATCH n-[:hasRoleInGroup]->hyperEdge-[:hasGroup]->group, hyperEdge-[:hasRole]->role
RETURN role.name, group.name
ORDER BY role.name asc

The groups and roles of User1

Result

role.namegroup.name
2 rows, 0 ms

"Role1"

"Group2"

"Role2"

"Group1"


5.1.3. Find common groups based on shared roles

Assume you have a more complicated graph:

  1. 2 user nodes User1, User2
  2. User1 is in Group1, Group2, Group3.
  3. User1 has Role1, Role2 in Group1; Role2, Role3 in Group2; Role3, Role4 in Group3 (hyper edges)
  4. User2 is in Group1, Group2, Group3
  5. User2 has Role2, Role5 in Group1; Role3, Role4 in Group2; Role5, Role6 in Group3 (hyper edges)

The graph for this looks like the following (nodes like U1G2R23 representing the HyperEdges):

Graph

To return Group1 and Group2 as User1 and User2 share at least one common role in those 2 groups, the cypher query looks like:

Query

START u1=node:node_auto_index(name = "User1"),u2=node:node_auto_index(name = "User2")
MATCH u1-[:hasRoleInGroup]->hyperEdge1-[:hasGroup]->group,
      hyperEdge1-[:hasRole]->role,
      u2-[:hasRoleInGroup]->hyperEdge2-[:hasGroup]->group,
      hyperEdge2-[:hasRole]->role
RETURN group.name, count(role)
ORDER BY group.name asc

The groups where User1 and User2 share at least one common role:

Result

group.namecount(role)
2 rows, 1 ms

"Group1"

1

"Group2"

1