这是你想要的吗?
MATCH (bob:User { name:"Bob" })-[:IN*0..]->(group)-[:AXO { read:true }]->(res1)-[:HAS*0..]->(res2 { name:"eVar 33" })
RETURN count(*)
我认为这个查询的意思是这样的:“给我用户 Bob,以及任何[:AXO{read:true}]
他与资源 eVar 33 的关系。您可以通过零个或多个[:IN]
通过 Bob 的组以及零个或多个来访问资源[:HAS]
,因为资源继承权限”。
>1
表示读取访问权限,0
意思是不是。
If your [:IN]
or [:HAS]
树木非常复杂,您可能需要限制深度。
Edit
关于通过返回找到的第一个路径进行优化的评论,如何以这种方式控制查询执行并不总是显而易见的,有时您必须知道 Cypher 何时以及如何惰性。将结果限制为 1 可能就足够了,但在这种情况下,稍微重新编写查询可能更切题,例如:“给我用户 Bob,如果他有任何[:AXO{read:true}]
与资源 eVar 33 的关系。您可能会经历...”
现在,从 Bob 到资源的路径是一个谓词,您的 Bob 在此基础上MATCH
子句被过滤。在 Cypher 中,类似的东西
MATCH (bob:User { name:"Bob" })
WHERE bob-[:IN*0..]->()-[:AXO { read:true }]->()-[:HAS*0..]->({ name:"eVar 33" })
RETURN true
如果路径谓词评估为 false,则不会返回任何内容。如果您想根据返回的内容而不是是否返回内容来确定权限,请不要使用WHERE
但只返回谓词的计数,或者更好的是谓词计数为 1 的断言。由于模式不是MATCH
子句不会扩展您的结果,因此计数将为 0 或 1(如果只有一个鲍勃)。
MATCH (bob:User { name:"Bob" })
RETURN 1 = count (bob-[:IN*0..]->()-[:AXO { read:true }]->()-[:HAS*0..]->({ name:"eVar 33" }))
它可能“感觉”就像计算路径谓词意味着计算路径,但事实并非如此。尝试删除{read:true}
要获得图中具有多个匹配项的路径模式 - 将其算作谓词仍然给出 1。
MATCH (bob:User { name:"Bob" })
RETURN 1 = count (bob-[:IN*0..]->()-[:AXO]->()-[:HAS*0..]->({ name:"eVar 33" }))
尝试分析这样的查询并与第一个查询进行比较LIMIT 1
看看哪个执行计划最有意义。