当遇到给定节点时,Neo4j停止搜索无向路径

时间:2018-07-18 11:41:38

标签: neo4j cypher

我在Neo4j中具有以下测试数据:

merge (n1:device {name:"n1"})-[:phys {name:"phys"}]->(:interface {name:"n1a"})-[:cable {name:"cable"}]->(:interface {name:"n2a"})-[:phys {name:"phys"}]->(n2:device {name:"n2"})
merge (n1)-[:phys {name:"phys"}]->(:interface {name:"n1b"})-[:cable {name:"cable"}]->(:interface {name:"n2b"})-[:phys {name:"phys"}]->(n2)
merge (n1)-[:phys {name:"phys"}]->(:interface {name:"n1c"})-[:cable {name:"cable"}]->(:interface {name:"n2c"})-[:phys {name:"phys"}]->(n2)
merge (n1)-[:phys {name:"phys"}]->(:interface {name:"n1d"})-[:cable {name:"cable"}]->(:interface {name:"n2d"})

给予:

enter image description here

尽管此示例在n1和n2之间的4条路径中的每条路径上都具有3个关系和2个节点,但是我的真实数据可能具有更多的路径,也有更多的路径。

这是一个无向图,在实际数据集中,每个路径的各个部分之间的关​​系是双向的。

我知道每个路径都以:device开始,或者只是以非:device结束,或者是以:device结束,并且一路上可能有任意数量的关系和其他非:device节点。

所以我想做:

match p=(:device {name:"n1"})-[*]-(:device) return (p)

并使其返回相同的记录数(我很乐意加倍),记录数为:

match p=(:device {name:"n1"})-[*]->(:device) return (p)

因此,我正在寻找一种方法来停止匹配关系并在路径中遇到第一个(:device)时停止遵循该路径。

据我有限的理解,我可以通过使每个关系都是双向的来轻松实现这一目标。但是,到目前为止,我已避免使用该选项,因为我已读到它是不好的做法。

额外给专家:-)

另外,我想一种返回不以:device结尾的完整路径的方法(例如,底部的路径)

谢谢

1 个答案:

答案 0 :(得分:2)

这是一个用例,仅使用Cypher有点困难,因为我们没有办法指定“遵循可变长度路径并在到达此类型的另一个节点时停止”。

当我们使用LIMIT时,我们可以做这样的事情,但是当我们不知道会有多少结果,或者我们需要对多个起始节点执行此操作时,这种限制就变得太严格了。

因此,有些APOC path finder procedures包含更灵活的选项。其中之一是labelFilter选项,该选项可让您描述如何过滤具有在扩展过程中找到的特定标签(黑名单,白名单等)的节点。这些过滤器之一称为termination filter(在适当的标签前使用/符号),这意味着将结果包括到该节点的路径,并停止扩展,这正是您所要做的。正在寻找。

安装APOC之后,可以从起始节点开始使用apoc.path.expandConfig()过程,并提供labelFilter config参数来获得以下行为:

MATCH (start:device {name:"n1"})
CALL apoc.path.expandConfig(start, {labelFilter:'/device'}) YIELD path
RETURN path