這是可能的。
讓我們創建一個示例圖:
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)
首先,得到節點標籤沿着某個路徑。我們首先使用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] │
└─────────┘