Reputation: 17631
I'm just starting out with Neo4j and I struggle a bit on the folling case. Given the following graph:
As "theo", I want to return the list of other user names who can also manage glossaries. Being member of a parent group should give you access to the same permissions as your children.
For example, for "theo", we should return sara and bob as sara is member of PoleManager which is a parent of ProjectManager group. Bob is member of ProjectManager group which have permission to manage glossaries.
So far I have the following query but it does not return sara as a candidate:
MATCH (me:User{name:"theo"})-[:MEMBER_OF]->(g:Group),
(g)-[:CAN_MANAGE]->(Asset{name:"Glossaries"}),
(users:User)-[:MEMBER_OF]->(g)
RETURN me.name AS Me, collect(users.name) AS Users
UNION MATCH (me:User{name:"theo"})-[:MEMBER_OF]->(Group)<-[:CHILD_OF*]-(children:Group),
(children)-[:CAN_MANAGE]->(Asset{name:"Glossaries"}),
(users:User)-[:MEMBER_OF]->(children)
RETURN me.name AS Me, collect(users.name) AS Users
I'm also open to better ideas to represent this graph.
Upvotes: 1
Views: 510
Reputation: 30397
The latter half of the query is almost right:
MATCH p = (me:User{name:$Me})-[:MEMBER_OF]->()<-[:CHILD_OF*0..]-()-[:CAN_MANAGE]->(:Asset{name:"Glossaries"})
UNWIND nodes(p)[1..-1] as group
MATCH (users:User)-[:MEMBER_OF]->(group)
RETURN $Me, collect(users.name) AS Users
If you're starting from the :User named "theo", then it should be enough to parameterize the name input, and return the name parameter in the RETURN instead of accessing it on the node, as above.
I'm also wondering if the match from Theo is really necessary, since it seems like all you want are users that are members of groups that can manage glossaries. If so, you can remove the Theo part from your query:
MATCH (users)-[:MEMBER_OF]->(group)<-[:CHILD_OF*0..]-()-[:CAN_MANAGE]->(:Asset{name:"Glossaries"})
RETURN $name collect(users.name) AS Users
For this one, I removed the labels for users and group, but you can only do this if your graph structure is well-defined enough that the relationships present here can only connect to :User and :Group nodes. If other types of nodes can also be connected by these relationships, you'll need to add the :User and :Group labels back on.
Upvotes: 1