的一般方法是找到到达所有所需的必要的关系/方向模式:从起始块节点:块节点,一旦你拥有所有这些:块节点,比赛的内容如下:输入,:输出和:属性节点。
这里最大的问题是关于您要遵循的模式的冲突关系方向。 :hasOutPort和:connectingTo都是外发的,这很好,但hasInPort关系指向相反的方向。
这是一个问题,因为使用多种关系类型的变长关系(这是解决此遍历的理想工具)只能为涉及的所有关系指定单个方向......如果我们让它成为任何方向,通过省略关系上的箭头),那么它将匹配incoming:connectedTo关系,这不是你想要的。
选项1:更改关系类型/方向
一个简单的建模解决将是改变之间的关系:输入节点和:块节点。
而不是你有什么目前:
(:Block)-[:hasInPort]->(:Input)
你也可以使用这样的:
(:Block)<-[:inPortFor]-(:Input)
如果你做出这种改变,那么路径你想一切都在同一个方向,查询变得容易:
// match from starting node to all :Block nodes along desired relationships
MATCH (:Block{name:'block_3'})-[:hasOutPort|:connectsTo|:inPortFor*0..]->(block:Block)
// use pattern comprehension to get lists of :Properties, :Input, and :Output nodes per :Block
WITH block, [(block)-[:PART_OF]->(prop) | prop] as properties,
[(block)-[:hasOutPort]->(output) | output] as outputs,
[(block)<-[:inPortFor]-(input) | input] as inputs
RETURN block, properties, outputs, inputs
如果您不能或不会改变关系的方向/类型之间的关系EN:输入和:块节点,那么你不能采取这种方法(第一个可变长度匹配),需要一个不同的方法。
选项2:APOC程序
APOC Procedures是Neo4j的一个插件,具有良好的一些非常有用的过程和函数。其中之一是path expander,它允许指定沿不同关系的扩展,并且可以声明每个单独关系类型遵循哪个方向。使用这个,以及终止标签过滤器(所以你只能得到匹配:块节点),我们可以替换第一个匹配。
// match from starting node to all :Block nodes along desired relationships
MATCH (start:Block{name:'block_3'})
CALL apoc.path.subgraphNodes(start, {labelFilter:'/Block',
relationshipFilter:'hasOutPort>|connectsTo>|<hasInPort'}) YIELD node as block
// use pattern comprehension to get lists of :Properties, :Input, and :Output nodes per :Block
WITH block, [(block)-[:PART_OF]->(prop) | prop] as properties,
[(block)-[:hasOutPort]->(output) | output] as outputs,
[(block)-[:hasInPort]->(input) | input] as inputs
RETURN block, properties, outputs, inputs