显然我对以下查询有误解,任何启示都会受到赞赏。
我一直在阅读关于UNIONS和cypher中的集合 - 特别是以下页面: https://neo4j.com/blog/cypher-union-query-using-collect-clause/
因此,如果配置文件具有权限,我决定尝试类似的返回(我认为节点图在这里相当明显,但如果需要可以提供一些创建)。
Match (p:Profile)-[:authorised]->(p1:Permission)
where p.username = 'user1'
with collect(p1) as directPerms
Match (p:Profile)-[:has_role]->(:Role)-[:authorised]->(p2:Permission)
where p.username = 'user1'
with directPerms + collect(p2) as plusRolePerms
Match (p:Profile)-[:member_of]->(:Group)-[:authorised]->(p3:Permission)
where p.username = 'user1'
with plusRolePerms + collect(p3) as allPerms
RETURN ANY(perm IN allPerms WHERE perm.id = 'ACCESS') as hasPermission
这是我被困的地方。假设用户确实具有'ACCESS'权限作为直接或角色权限但具有0组权限,那么查询根本不返回任何内容!
我假设我误解了将列表添加到一起。我也知道我没有按照网页上的说明使用UNWIND,但是,我没有进行任何查询后排序/操作,所以假设我不需要......?
任何帮助将不胜感激:D
修改的
我接受了这个问题的答案,因为它解决了部分问题。我特别喜欢的解决方案是:
MATCH (p:Profile {username: 'user1'}), (a:Permission {id: 'ACCESS'})
RETURN
(p)-[:authorised]->(a) OR
(p)-[:has_role]->(:Role)-[:authorised]->(a) OR
(p)-[:member_of]->(:Group)-[:authorised]->(a)
AS hasPermission
因为它保持清晰(尽管@InverseFalcon也有更短的可能更快的解决方案)。
答案 0 :(得分:3)
这是一个简洁的Cypher查询,它也更有效(因为它不需要维护不断增长的集合)。它还有可能生成一个执行计划,一旦找到latin1_swedish_ci
id值就会完成查询(但当前的Cypher规划人员可能尚未生成此类计划)。
ACCESS
[编辑]
或者,更好的是,如果只有MATCH (p:Profile {username: 'user1'})
RETURN
(p)-[:authorised]->(:Permission {id: 'ACCESS'}) OR
(p)-[:has_role]->(:Role)-[:authorised]->(:Permission {id: 'ACCESS'}) OR
(p)-[:member_of]->(:Group)-[:authorised]->(:Permission {id: 'ACCESS'})
AS hasPermission;
个Permission
个ACCESS
个节点:
MATCH (p:Profile {username: 'user1'}), (a:Permission {id: 'ACCESS'})
RETURN
(p)-[:authorised]->(a) OR
(p)-[:has_role]->(:Role)-[:authorised]->(a) OR
(p)-[:member_of]->(:Group)-[:authorised]->(a)
AS hasPermission;
或者,正如@InverseFalcon建议的那样,您可以执行以下操作(我再次假设,只有一个Permission
节点具有ACCESS
id。这会生成最简单的执行计划,但更难理解:
MATCH (p:Profile {username: 'user1'}), (a:Permission {id: 'ACCESS'})
RETURN (p)-[:has_role|member_of*0..1]-()-[:authorised]->(a) AS hasPermission;
答案 1 :(得分:1)
如果您将所有权限匹配OPTIONAL MATCH
并将用户匹配分开,那么在用户不存在的情况下,您将永远不会返回结果。作为奖励,您只需要找到一次用户节点而不是三次。
MATCH (p:Profile)
WHERE p.username = 'user1'
WITH p
OPTIONAL MATCH (p)-[:authorised]->(p1:Permission)
WITH p, collect(p1) as directPerms
OPTIONAL MATCH (p)-[:has_role]->(:Role)-[:authorised]->(p2:Permission)
WITH p, directPerms + collect(p2) as plusRolePerms
OPTIONAL MATCH (p)-[:member_of]->(:Group)-[:authorised]->(p3:Permission)
WITH p, plusRolePerms + collect(p3) as allPerms
RETURN ANY(perm IN allPerms WHERE perm.id = 'ACCESS') as hasPermission