2016-09-20 76 views
0

的Cypher查詢我有一個有序列表有序列表

(父) - [:NEXT] - >(項目) - [:NEXT] - >(項目)... [:NEXT] - >(項目)

我想找出找到所有項目的高效密碼查詢。關係:NEXT只從一個項目到下一個項目,而且從不重複,我沒有一個循環。

這是我的暗號查詢

START n=node(nodeId) MATCH (n)-[r:NEXT*]->(m:ListItem) RETURN distinct(m) 

這工作,但令人難以置信的速度慢甚至對於具有10項的列表,因爲它顯然是繞着查詢。對於長度爲3和*替換爲* 1..3並清除的列表,我有45個節點。我不明白爲什麼。不同的是我得到了我認爲我應該得到的3個節點。

+0

請給出一個數據的例子。 –

+0

無法找到一種輕鬆導出有助於玩遊戲的數據的方法。導出要在此處顯示的示例數據的好方法是什麼?但我找到了解決這個問題的辦法。 – Antti

回答

1

這是一個答案,以有效地做到這一點(假設所有列表項都受到關係LIST_ITEM鏈接到父

MATCH (n) WHERE id(n)={nodeId} WITH n 
     MATCH (n)-[:LIST_ITEM]-(m:ListItem) WHERE NOT (m)-[:NEXT]->() 
     WITH n, m 
     MATCH path = (n)-[:NEXT*]->(m) 
     RETURN FILTER (a in nodes(path) WHERE ANY (l in labels(a) WHERE l="ListItem")) 
     LIMIT 1 

簡單的查詢,歡迎

+1

請注意,對於最新版本的Neo4j,通過id查找節點的正確方法是匹配(n)WHERE id(n)= {nodeId}'。自從Cypher 2.2以來,「START」的使用僅限於傳統的索引。 –

+0

您在這裏使用的2種關係具有不同的功能。問題中的'm'也是'ListItem'?它是「父母」還是鏈接列表的頭部? –

+0

我編輯了我的回覆,因爲顯然我使用'm'和'p'作爲同一節點來混淆人。 'm'也是'ListItem'。原來我的問題也是 - 我沒有注意到 - 我從'n'到它本身具有':NEXT'關係,這延長了查詢時間。 – Antti

0

重組你的問題,你正在尋找一個的完整的路徑時,遍歷:NEXT關係,但不一定是最長路徑。不清楚遍歷:NEXT關係總是導致ListItem節點,bas在你自己的答案中對查詢進行編輯。

您的查詢可以簡化爲:

MATCH p = (head:ListItem)-[:NEXT*]->(tail:ListItem) 
WHERE id(head) = {nodeId} 
    AND NOT (tail)-[:NEXT]->() 
RETURN filter(n IN nodes(p) WHERE n:ListItem) 
LIMIT 1 

甚至,如果只有ListItem路徑節點:

MATCH p = (head:ListItem)-[:NEXT*]->(tail:ListItem) 
WHERE id(head) = {nodeId} 
    AND NOT (tail)-[:NEXT]->() 
RETURN nodes(p) 
LIMIT 1 

沒有必要掃描通過:LIST_ITEM關係到項目找到可能的尾巴,因爲無論如何要遍歷可變長度關係,以查找路徑中的節點:只進行遍歷並僅包含無法擴展的路徑。