Neo4j使用属性过滤器通过多个关系定向路径 [英] Neo4j directed path through multiple relationships with property filter

查看:191
本文介绍了Neo4j使用属性过滤器通过多个关系定向路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为Cypher和Neo4j的新手,我在为用例构造查询时遇到麻烦.我正在构建一个简单的ACL(访问控制列表),并且也在通过权限关系以及层次结构中寻找路径.图片可能会更好地解释它:

Being new to Cypher and Neo4j, I am having trouble constructing my query for my use-case. I am building a simple ACL (access control list) and am looking for a path through permission relationships an up a hierarchy as well. A picture may better explain it:

Key:
    Users -> Blue
    Groups -> Yellow, Green
    Resource Tree -> Red

现在,我想看看是否存在从Bob到Bob具有 update 访问权限的 eVar 33 资源的路径.因为有一条直接的道路,所以我可以通过跑步获得想要的东西

Now I want to see if a path exists from Bob to the eVar 33 resource where Bob has update access. Because there is a direct path, I can get what I am looking for by running

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

但是现在,鲍勃还是 Media Mgmt 组的成员,该组授予他 read Conversion 资源的访问权限.并且由于 Conversion eVar 33 在资源树的上方,因此 eVar 33 应该继承此权限.但是,当我运行相同的查询来查找{read: true}时,找不到任何路径.我知道这是因为我不允许遍历:IN:HAS关系,但是我该怎么做?

But now, Bob is also a member of the Media Mgmt group which grants him read access to the Conversion resource. And because Conversion is further up the resource tree than eVar 33, eVar 33 should inherit this permission. But when I run the same query looking for {read: true} instead, no path is found. I know this is because I am not allowing traversal through the :IN and :HAS relationships, but how can I do this?

我尝试过:

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

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

thinking this would allow those relationships to be traversed, but it still does not find a path (because I am not allowing more than a depth of 1?).

这是我的需求:

  • 未知的路径深度
  • 我返回的任何路径都很好(我真正关心的是是否有路径?")
  • 必须能够从用户获取资源,并且在遵循AXO关系时,它必须与属性过滤器匹配.
  • 必须遵循有向图(例如Bob没有对 Analytics 的权限)
  • Unknown depth of path
  • Any path(s) I get back are fine (all I really care about is "Is there a path or not?")
  • Must be able to get from a user to a resource AND when an AXO relationship is being followed it must match a property filter.
  • Must follow the directed graph (i.g. Bob has no permissions for Analytics)

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

推荐答案

这是您想要的吗?

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

我认为该查询的含义是:给用户Bob和他必须为eVar 33提供资源的任何[:AXO{read:true}]关系.您可以通过零个或多个[:IN]来访问Bob的组,并通过零个或多个[:HAS],因为资源继承了权限".

I take this query to mean something like: "Give me user Bob, and any [:AXO{read:true}] relationship that he has to resource eVar 33. You may go to through zero or more [:IN] to access the resource through Bob's groups, and through zero or more [:HAS], since resources inherit permissions".

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

>1 means read access, 0 means not.

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

If your [:IN] or [:HAS] trees are very complex you may want to cap depth.

修改
关于通过返回找到的第一个路径进行优化的评论,如何以这种方式控制查询执行并不总是很明显,有时您必须知道Cypher的懒惰时间和方式.将结果限制为1可能就足够了,但是在这种情况下,稍微重新调整查询就可以了,例如:如果用户Bob与资源eVar 33有任何[:AXO{read:true}]关系,请给我. "

Edit
Wrt comment about optimizing by returning on first path found, it's not always obvious how to control query execution this way, sometimes you have to know when and how Cypher is lazy. Limiting result to 1 may suffice, but in this case reformulating the query slightly may be more to the point, something like: "Give me user Bob if he has any [:AXO{read:true}] relationship to resource eVar 33. You may go through..."

现在,从Bob到资源的路径是一个谓词,您的MATCH子句中的Bob会在此谓词上进行过滤.在Cypher中,类似

Now the path from Bob to resource is a predicate on which the Bobs in your MATCH clause are filtered. In Cypher, something like

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(如果只有一个鲍勃).

This will not return anything if the path predicate evaluates false. If you want to determine permission based on what is returned rather than whether something is returned, don't use WHERE but just return a count of the predicate, or better an assertion that the count of the predicate is 1. Since the pattern is not part of the MATCH clause it will not expand your result, so counting will be 0 or 1 (if there is only one Bob).

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

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

It may 'feel' like counting the path predicate would mean counting the paths, but it doesn't. Try removing {read:true} to get a path pattern with more than one matches in the graph–counting it as a predicate still gives 1.

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

尝试对此类查询进行性能分析,并使用LIMIT 1与第一个查询进行比较,以了解哪种执行计划最有意义.

Try profiling such a query and compare to the first query with a LIMIT 1 to see which execution plan makes most sense.

这篇关于Neo4j使用属性过滤器通过多个关系定向路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆