微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Cypher 通过关系和节点的模式返回多跳

如何解决Cypher 通过关系和节点的模式返回多跳

我正在使用 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)

但是这没有任何方向,我无法弄清楚如何在不将返回的匹配项减少到仅直接匹配项的情况下包含这些方向(即它不会在第一次点击 {{1 }} 节点)

所以我想知道的是:

  1. 有没有办法在一个查询中匹配多个这些跃点?
  2. 我应该完全不同的建模吗?
  3. 我是不是完全走错了路,查询应该完全是 重写

解决方法

目前,可变长度扩展的语法不允许对某些类型的单独方向进行精细控制。管道中围绕此进行了改进,但目前仅靠 Cypher 无法满足您的需求。

我们可以为此使用 APOC 过程,因为 path expander procs 支持对扩展中类型方向和关系序列的精细控制。

首先,您需要弄清楚如何解决您的用户或业务匹配问题,方法是向这些节点添加一个公共标签,您可以通过该标签按属性进行匹配,或者您可以使用子查询使用两个 UNIONed 查询,一个用于 :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 设置为:业务节点是路径的结束节点,而不是任何其他标签的节点。

,

您可以指定路径如下:

MATCH path = (:User {userId: $id})-[:can]->(:Permission)
    <-[:allows]-(:Business))
RETURN path

这应该会返回您想要的结果。

,

我看到通过路径扩展 APOC 程序提供了一个很好的解决方案。
但我会关注你的观点 #2:“我应该完全不同地建模吗?” 嗯,不完全,但我认为是的。

使用 Neo4j 真正解放的部分是,您可以像改变驾驶策略一样轻松地改变正在行驶的道路:模型与查询。由于您处于项目的早期阶段,您可以尝试不同的模型。这是一个很好的机会,可以只是改变语义,从而“终结”问题。

Neo4j 中关系的语义通过

表示
  1. 您分配给关系的强制类型,结合
  2. 您选择指向强制箭头的方向

您使用 APOC 解决的技巧是如何遍历关系路径,这些关系路径沿查询路径在向前和向后之间交替。但是,在使用强力工具之前,为什么不扭转您的任何一种关系类型的方向。您可以从

更改允许的模型
<-[:allows]-

-[:is_allowed_by]->

这会给你带来很多好处。现在这两个关系的方向是相同的,您可以在匹配模式中将这两个关系合并为一个关系。而路径遍历可以这样表达,短小精悍:

(u:User)-[:can|is_allowed_by*]->(c:Company)

这将不遗余力地找到每个用户到公司的路径,包括分支。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。