Neo4j通过属性过滤器指导路径与多个关系

Eri*_*son 5 acl neo4j cypher

作为Cypher和Neo4j的新手,我无法构建我的用例查询.我正在构建一个简单的ACL(访问控制列表),并且正在寻找通过权限关系的路径.一张图片可以更好地解释它:

在此输入图像描述

Key:
    Users -> Blue
    Groups -> Yellow, Green
    Resource Tree -> Red
Run Code Online (Sandbox Code Playgroud)

现在我想看看Bob是否存在路径到Bob拥有更新访问权限的eVar 33资源.因为有直接的路径,我可以通过跑步得到我想要的东西

MATCH p =(usr:Usr)-[:AXO {update: true}]->(aco:ACO)
WHERE usr.name = 'Bob' AND aco.name = 'eVar 33'
RETURN p
Run Code Online (Sandbox Code Playgroud)

但现在,Bob也是Media Mgmt小组的成员,该小组授予他对转换资源的读取权限.并且因为转换eVar 33更靠资源树,eVar 33应该继承此权限.但是当我运行相同的查询时,没有找到路径.我知道这是因为我不允许遍历和关系,但我怎么能这样做?{read: true}:IN:HAS

我试过了:

MATCH p =(usr:Usr)-[:IN|:HAS|:AXO {read: true}]->(aco:ACO)
WHERE usr.name = 'Bob' AND aco.name = 'eVar 33'
RETURN p
Run Code Online (Sandbox Code Playgroud)

认为这会允许遍历这些关系,但它仍然找不到路径(因为我不允许超过1的深度?).

所以这是我的需求:

  • 未知的路径深度
  • 我回来的任何路径都很好(我真正关心的是"是否有路径?")
  • 必须能够从用户获取资源并且当遵循AXO关系时,它必须与属性过滤器匹配.
  • 必须遵循有向图(ig Bob没有Google Analytics的权限)

不,我不为耐克工作.这里只是一个用例示例:)

jja*_*erg 5

这样做你想要的吗?

MATCH (bob:User { name:"Bob" })-[:IN*0..]->(group)-[:AXO { read:true }]->(res1)-[:HAS*0..]->(res2 { name:"eVar 33" })
RETURN count(*)
Run Code Online (Sandbox Code Playgroud)

我把这个问题看作是这样的:"给我用户Bob,以及[:AXO{read:true}]他对资源eVar 33的任何关系.你可以通过零个或多个[:IN]来通过Bob的组访问资源,并通过零或更多[:HAS],因为资源继承权限".

>1表示读访问,0表示不是.

如果您[:IN][:HAS]树木非常复杂,您可能需要限制深度.


通过返回找到的第一条路径来编辑关于优化的Wrt评论,如何以这种方式控制查询执行并不总是显而易见的,有时你必须知道Cypher何时以及如何懒惰.将结果限制为1可能就足够了,但在这种情况下,稍微重新构造查询可能更重要,例如:"如果他[:AXO{read:true}]与资源eVar 33 有任何关系,请给我用户Bob .你可以通过......"

现在,从Bob到资源的路径是一个谓词,您的MATCH子句中的Bobs将被过滤掉.在Cypher,类似的东西

MATCH (bob:User { name:"Bob" })
WHERE bob-[:IN*0..]->()-[:AXO { read:true }]->()-[:HAS*0..]->({ name:"eVar 33" })
RETURN true
Run Code Online (Sandbox Code Playgroud)

如果路径谓词评估为false,则不会返回任何内容.如果要根据返回的内容而不是返回某些内容来确定权限,请不要使用WHERE但只返回谓词的计数,或者更好地断言谓词的计数为1.因为模式不是部分该MATCH子句不会扩展您的结果,因此计数将为0或1(如果只有一个Bob).

MATCH (bob:User { name:"Bob" })
RETURN 1 = count (bob-[:IN*0..]->()-[:AXO { read:true }]->()-[:HAS*0..]->({ name:"eVar 33" }))
Run Code Online (Sandbox Code Playgroud)

它可能"感觉"像计算路径谓词意味着计算路径,但事实并非如此.尝试删除{read:true}以获得图形中具有多个匹配的路径模式 - 将其计数为谓词仍然为1.

MATCH (bob:User { name:"Bob" })
RETURN 1 = count (bob-[:IN*0..]->()-[:AXO]->()-[:HAS*0..]->({ name:"eVar 33" }))
Run Code Online (Sandbox Code Playgroud)

尝试分析这样的查询并与第一个查询进行比较,LIMIT 1以查看哪个执行计划最有意义.