2016-12-05 101 views
0

我知道有兩種類型的節點,說(:RefNodeType1)(:RefNodeType2)。兩者在給定的圖中都會有單個實例。然後我知道有另外兩種類型的節點(:TargetNodeType1)(:TargetNodeType2)以及它們中的每一個的多個實例。獲取兩個節點之間的路徑並使用它來匹配兩個其他類型的節點

我想知道(:TargetNodeType1)(:TargetNodeType2)的所有實例,它們之間的路徑與(:RefNodeType1)(:RefNodeType2)之間的路徑相同。在說「同一條路徑」時,我的意思是說,兩條路徑上的關係和節點標籤應該相同,並且應該以相同的順序出現。

僞暗號可能是這個樣子

MATCH path = (:RefNodeType1)-<path-description>-(RefNodeType2) //<path-description> can be anything, may include variable length relationship e.g. [:XYZ*1..] 
WITH path 
MATCH (a:TargetNodeType1)-<path>-(b:TargetNodeType2) 
RETURN a,b 

但我不知道我怎麼可以指定<path>,即如果包含的變量path路徑也TargetNodeType1TargetNodeType2之間。我不知道這樣的查詢是否可能。但是,我仍然可以如何做到這一點?還有什麼可以更好的方法呢?

回答

0

這是可能的。

讓我們創建一個示例圖:

CREATE 
    (rn1:RefNodeType1 {name: "rn1"}), 
    (rn2:RefNodeType2 {name: "rn2"}), 
    (tn1:TargetNodeType1 {name: "tn1"}), 
    (tn2:TargetNodeType2 {name: "tn2"}), 
    (i1:IntermediateNodeType {name: "i1"}), 
    (i2:IntermediateNodeType {name: "i2"}), 
    (rn1)-[:REL]->(i1)-[:REL]->(rn2), 
    (tn1)-[:REL]->(i2)-[:REL]->(tn2) 

enter image description here

首先,得到節點標籤沿着某個路徑。我們首先使用nodes()函數來提取路徑的節點。爲了獲得中間節點,我們使用[1..length(nodes)-1]範圍(請注意,上限爲non-inclusive,例如RETURN ['a', 'b', 'c'][1..2]返回['b'])丟棄第一個和最後一個節點。我們UNWIND中間節點,以便我們可以調用它們中的每一個的labels()方法,並將collect的結果調用到列表中。

MATCH path = (:RefNodeType1)-[r*]->(:RefNodeType2) 
WITH nodes(path) AS nodes 
WITH nodes[1..length(nodes)-1] AS refIntermediateNodes 
UNWIND refIntermediateNodes AS refIntermediateNode 
WITH collect(labels(refIntermediateNode)) AS refIntermediateNodeLabels 
RETURN * 

這導致:

╒═════════════════════════╕ 
│refIntermediateNodeLabels│ 
╞═════════════════════════╡ 
│[[IntermediateNodeType]] │ 
└─────────────────────────┘ 

我們應用這兩個RefNodeType S和TargetNodeType秒。

// (1) 
MATCH path = (:RefNodeType1)-[r*]->(:RefNodeType2) 
WITH nodes(path) AS nodes 
WITH nodes[1..length(nodes)-1] AS refIntermediateNodes 
UNWIND refIntermediateNodes AS refIntermediateNode 
WITH collect(labels(refIntermediateNode)) AS refIntermediateNodeLabels 
// (2) 
MATCH path = (t1:TargetNodeType1)-[r*]->(t2:TargetNodeType2) 
WITH t1, t2, refIntermediateNodeLabels, nodes(path) AS nodes 
WITH t1, t2, refIntermediateNodeLabels, nodes[1..length(nodes)-1] AS targetIntermediateNodes 
UNWIND targetIntermediateNodes AS targetIntermediateNode 
WITH t1, t2, refIntermediateNodeLabels, collect(labels(targetIntermediateNode)) AS targetIntermediateNodeLabels 
WHERE refIntermediateNodeLabels = targetIntermediateNodeLabels 
RETURN t1, t2 

注意,在第二MATCH(2)中,我們需要通過refIntermediateNodeLabels每個WITH條款(如WITH​​)。

結果是:

╒═══════════╤═══════════╕ 
│t1   │t2   │ 
╞═══════════╪═══════════╡ 
│{name: tn1}│{name: tn2}│ 
└───────────┴───────────┘ 

,當然我們要爲關係也這麼做 - 的主要區別是:1)我們沒有放棄的第一個和最後一個2)我們必須使用type()而不是labels()

因此,要沿路徑的關係:

MATCH path = (:RefNodeType1)-[r*]->(:RefNodeType2) 
WITH relationships(path) AS refRelationships 
UNWIND refRelationships AS refRelationship 
WITH collect(type(refRelationship)) AS refRelationshipLabels 
RETURN * 

這導致是:

╒═════════════════════╕ 
│refRelationshipLabels│ 
╞═════════════════════╡ 
│[REL_A, REL_B]  │ 
└─────────────────────┘ 

因此,讓我們添加這一切在一起,使我們得到這個漂亮的&簡單的查詢:

// (1) 
MATCH path = (:RefNodeType1)-[r*]->(:RefNodeType2) 
WITH nodes(path) AS nodes, relationships(path) AS refRelationships 
WITH nodes[1..length(nodes)-1] AS refNodes, refRelationships 
UNWIND refNodes AS refNode 
WITH refNodes, collect(labels(refNode)) AS refNodeLabels, refRelationships 
UNWIND refRelationships AS refRelationship 
WITH refNodeLabels, collect(type(refRelationship)) AS refRelationshipLabels 
// (2) 
MATCH path = (t1:TargetNodeType1)-[r*]->(t2:TargetNodeType2) 
WITH t1, t2, refNodeLabels, refRelationshipLabels, nodes(path) AS nodes, relationships(path) AS targetIntermediateRelationships 
WITH t1, t2, refNodeLabels, refRelationshipLabels, nodes[1..length(nodes)-1] AS targetIntermediateNodes, targetIntermediateRelationships 
UNWIND targetIntermediateNodes AS targetIntermediateNode 
WITH t1, t2, refNodeLabels, refRelationshipLabels, collect(labels(targetIntermediateNode)) AS targetIntermediateNodeLabels, targetIntermediateRelationships 
UNWIND targetIntermediateRelationships AS targetIntermediateRelationship 
WITH t1, t2, refNodeLabels, refRelationshipLabels, targetIntermediateNodeLabels, collect(type(targetIntermediateRelationship)) AS targetIntermediateRelationshipLabels 
WHERE refNodeLabels = targetIntermediateNodeLabels 
    AND refRelationshipLabels = targetIntermediateRelationshipLabels 
RETURN t1, t2 

限制:我不是當然這將適用於多個節點標籤 - 但它們似乎以相同的順序返回:

CREATE (:A:B), (:B:A) 

MATCH (n:A) 
RETURN labels(n) 

╒═════════╕ 
│labels(n)│ 
╞═════════╡ 
│[A, B] │ 
├─────────┤ 
│[A, B] │ 
└─────────┘ 
相關問題