Cypher return 通过关系和节点模式进行多次跳跃
Cypher return multiple hops through pattern of relationships and nodes
我正在使用 neo4j 制作概念验证访问控制系统,我需要 Cypher 方面的帮助。
数据模型如下:
(:User|Business)-[:can]->(:Permission)<-[:allows]-(:Business)
现在我想获得一条从用户或企业到您可以通过
到达的所有业务节点的路径
-[:can]->(:Permission)<-[:allows]-
模式。我已经设法写了一个让我走到一半的 MATCH:
MATCH
path =
(:User {userId: 'e96cca53-475c-4534-9fe1-06671909fa93'})-[:can|allows*]-(b:Business)
但这没有任何指示,我无法弄清楚如何在不将返回的匹配减少为仅直接匹配的情况下包含指示(即在第一次点击 :Business
节点)
所以我想知道的是:
- 有没有办法在一个查询中匹配多个这些跃点?
- 我应该用完全不同的方式建模吗?
- 我是不是完全走错了路,查询应该是完全正确的
重写
您可以指定路径如下:
MATCH path = (:User {userId: $id})-[:can]->(:Permission)
<-[:allows]-(:Business))
RETURN path
这应该 return 您想要的结果。
目前,可变长度扩展的语法不允许对某些类型的单独方向进行精细控制。围绕这个问题的管道有所改进,但目前仅靠 Cypher 无法满足您的需求。
我们可以为此使用 APOC 程序,因为 path expander procs.
支持扩展中类型方向的精细控制和关系序列
不过,首先,您需要弄清楚如何解决您的用户或业务匹配问题,方法是向这些节点添加一个公共标签,您可以通过 属性 匹配任一类型,或者您可以使用带有两个 UNION 查询的子查询,一个用于 :Business 节点,另一个用于 :User 节点,这样您仍然可以利用其中任何一个的索引,并在单个变量中获得可能的结果。
一旦你得到它,你可以使用 apoc.path.expandConfig()
,传递一些选项来得到你想要的:
// assume you've matched to your `start` node already
CALL apoc.path.expandConfig(start, {relationshipFilter:'can>|<allows', labelFilter:'>Business'}) YIELD path
RETURN path
这个不使用序列,但它确实限制了每个关系类型的扩展方向。我们还设置了 labelFilter 使得:业务节点是路径的结束节点,而不是任何其他标签的节点。
我看到通过路径扩展 APOC 程序提供了一个很好的解决方案。
但我将重点关注您的第 2 点:“我应该完全不同地建模吗?”
好吧,不完全是,但我认为是的。
使用 Neo4j 真正解放的部分是,您可以像更改驾驶策略一样轻松地改变您行驶的道路:模型与查询。由于您处于项目的早期阶段,您可以尝试不同的模型。有一个很好的机会 只是 一个语义上的改变来 'end run' 解决这个问题。
Neo4j 中关系的语义是通过
表达的
- 您分配给关系的强制类型,结合
- 您选择指向强制箭头的方向
您使用 APOC 解决的技巧是如何遍历一条关系路径,该路径沿查询路径向前和向后交替。但在使用强大的工具之前,为什么不扭转你的任何一种关系类型的方向。您可以从
更改允许模型
<-[:allows]-
至
-[:is_allowed_by]->
这给你带来了很多好处。现在两个关系的方向相同,您可以在匹配模式中将两个关系合并为一个关系。路径遍历可以这样表达,简短而甜蜜:
(u:User)-[:can|is_allowed_by*]->(c:Company)
这将不遗余力地找到每个用户到公司的路径,包括分支。
我正在使用 neo4j 制作概念验证访问控制系统,我需要 Cypher 方面的帮助。
数据模型如下:
(:User|Business)-[:can]->(:Permission)<-[:allows]-(:Business)
现在我想获得一条从用户或企业到您可以通过
到达的所有业务节点的路径 -[:can]->(:Permission)<-[:allows]-
模式。我已经设法写了一个让我走到一半的 MATCH:
MATCH
path =
(:User {userId: 'e96cca53-475c-4534-9fe1-06671909fa93'})-[:can|allows*]-(b:Business)
但这没有任何指示,我无法弄清楚如何在不将返回的匹配减少为仅直接匹配的情况下包含指示(即在第一次点击 :Business
节点)
所以我想知道的是:
- 有没有办法在一个查询中匹配多个这些跃点?
- 我应该用完全不同的方式建模吗?
- 我是不是完全走错了路,查询应该是完全正确的 重写
您可以指定路径如下:
MATCH path = (:User {userId: $id})-[:can]->(:Permission)
<-[:allows]-(:Business))
RETURN path
这应该 return 您想要的结果。
目前,可变长度扩展的语法不允许对某些类型的单独方向进行精细控制。围绕这个问题的管道有所改进,但目前仅靠 Cypher 无法满足您的需求。
我们可以为此使用 APOC 程序,因为 path expander procs.
支持扩展中类型方向的精细控制和关系序列不过,首先,您需要弄清楚如何解决您的用户或业务匹配问题,方法是向这些节点添加一个公共标签,您可以通过 属性 匹配任一类型,或者您可以使用带有两个 UNION 查询的子查询,一个用于 :Business 节点,另一个用于 :User 节点,这样您仍然可以利用其中任何一个的索引,并在单个变量中获得可能的结果。
一旦你得到它,你可以使用 apoc.path.expandConfig()
,传递一些选项来得到你想要的:
// assume you've matched to your `start` node already
CALL apoc.path.expandConfig(start, {relationshipFilter:'can>|<allows', labelFilter:'>Business'}) YIELD path
RETURN path
这个不使用序列,但它确实限制了每个关系类型的扩展方向。我们还设置了 labelFilter 使得:业务节点是路径的结束节点,而不是任何其他标签的节点。
我看到通过路径扩展 APOC 程序提供了一个很好的解决方案。
但我将重点关注您的第 2 点:“我应该完全不同地建模吗?”
好吧,不完全是,但我认为是的。
使用 Neo4j 真正解放的部分是,您可以像更改驾驶策略一样轻松地改变您行驶的道路:模型与查询。由于您处于项目的早期阶段,您可以尝试不同的模型。有一个很好的机会 只是 一个语义上的改变来 'end run' 解决这个问题。
Neo4j 中关系的语义是通过
表达的- 您分配给关系的强制类型,结合
- 您选择指向强制箭头的方向
您使用 APOC 解决的技巧是如何遍历一条关系路径,该路径沿查询路径向前和向后交替。但在使用强大的工具之前,为什么不扭转你的任何一种关系类型的方向。您可以从
更改允许模型<-[:allows]-
至
-[:is_allowed_by]->
这给你带来了很多好处。现在两个关系的方向相同,您可以在匹配模式中将两个关系合并为一个关系。路径遍历可以这样表达,简短而甜蜜:
(u:User)-[:can|is_allowed_by*]->(c:Company)
这将不遗余力地找到每个用户到公司的路径,包括分支。