的一般方法是找到到達所有所需的必要的關係/方向模式:從起始塊節點:塊節點,一旦你擁有所有這些:塊節點,比賽的內容如下:輸入,:輸出和:屬性節點。
這裏最大的問題是關於您要遵循的模式的衝突關係方向。 :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