2017-07-03 76 views
6

我有一個Neo4j的圖形看起來像這樣間的任意路徑:暗號:查找節點

Graph overview

節點:

  1. 藍色節點:帳戶
  2. 紅色節點:******中國
  3. 綠色節點:電子郵件

圖形設計:

  • (:******中國) - [:PART_OF] - >(:帳戶)
  • (:電子郵件) - [:PART_OF] - >(:帳戶)

我試圖解決的問題是

查找帳戶1和帳戶2之間存在任何路徑。

這是我一直沒有成功到目前爲止已經試過:

  1. MATCH P =最短路徑((A1:帳戶{ACCID: '1234'}) - [] - (A2:帳戶{ accId:'5678'}))RETURN p;
  2. MATCH p = shortestPath((a1:Account {accId:'1234'}) - [:PART_OF] - (a2:Account {accId:'5678'}))RETURN p;
  3. MATCH p = shortestPath((a1:Account {accId:'1234'}) - [*] - (a2:Account {accId:'5678'}))RETURN p;
  4. MATCH p =(a1:Account {accId:'1234'})< - [:PART_OF * 1..100] - (n) - [:PART_OF] - >(a2:Account {accId:'5678' })RETURN p;
  5. 與上面相同的查詢沒有最短路徑函數調用。

通過查看圖我可以看到這兩個節點之間存在路徑,但是我的查詢中沒有任何結果存在。我確信這是一個非常簡單的查詢,但對Cypher來說是新的,我很難找出正確的解決方案。任何幫助表示讚賞。

謝謝。

+0

您能否提供更多關於運行這些查詢時會發生什麼的細節? –

回答

4

所有這些查詢都沿着正確的路線,但需要一些調整才能完成工作。然而,從長遠來看,爲了獲得更好的系統來輕鬆搜索帳戶之間的連接,您可能需要重構圖形。

解決方案現在:使你的查詢工作

在圖形中任意兩個(n:Account)節點之間的路徑將會是這個樣子:

(a1:Account)<-[:PART_OF]-(:Email)-[:PART_OF]->(ai:Account)<-[:PART_OF]-(:PhoneNumber)-[:PART_OF]->(a2:Account)

因爲你只有一次類型的關係在圖中,兩個節點因此將通過如下的不確定數目的模式連接:

<-[:PART_OF]-(:Email)-[:PART_OF]->

<-[:PART_OF]-(:PhoneNumber)-[:PART_OF]->

所以,你的兩個節點將通過所有通過交替方向的-[:PART_OF]-關係連接中間(:Account)(:Email),或(:PhoneNumber)節點的數目不確定連接。不幸的是,據我所知(我很想在這裏糾正),使用直接密碼,你不能在你當前的圖表中搜索這樣的重複模式。因此,您只需使用無向搜索,即可找到通過-[:PART_OF]-關係連接的節點(a1:Account)(a2:Account)。所以,乍一看您的查詢應該是這樣的:

MATCH p=shortestPath((a1:Account { accId: {a1_id} })-[:PART_OF*]-(a2:Account { accId: {a2_id} })) 
RETURN * 

(注意這裏我用cypher parameters,而不是你把在原崗位的整數)

這是非常相似的查詢#3 ,但是,就像你說的那樣 - 它不起作用。我猜測會發生什麼,它不會返回結果,或返回內存不足異常?問題是由於你的圖有循環路徑,並且該查詢將匹配任何長度的路徑,所以匹配算法將逐字地繞圈,直到它耗盡內存。所以,你想設置一個限制,就像你在查詢#4中,但沒有方向(這就是爲什麼該查詢不起作用)。

所以,我們設置一個限制。 100個關係的限制在很大的一方有一點點,特別是在一個循環圖(即一個包含圓的圖)中,並且可能在2^100個路徑的區域內匹配。作爲(非常隨意的)經驗法則,任何查詢的潛在無向和未標記的路徑長度超過5或6可能會導致問題,除非您對圖形設計非常小心。在你的例子中,它看起來像這兩個節點通過8的路徑長度連接。我們還知道,對於任何兩個節點,給定的最小路徑長度將是兩個(即兩個-[:PART_OF]-關係,一個進入和一個進出一個節點標記爲:Email:PhoneNumber),並且任何兩個帳戶(如果已鏈接)都將通過偶數關係進行關聯。

因此,理想情況下我們要設定我們的關係長度在2到10之間。但是,密碼的shortestPath()函數只支持最小長度爲0或1的路徑,所以我在1和10之間設置了它。下面的例子(儘管我們知道實際上最短路徑的長度至少爲2)。

MATCH p=shortestPath((a1:Account { accId: {a1_id} })-[:PART_OF*1..10]-(a2:Account { accId: {a2_id} })) 
RETURN * 

希望,這會影響您使用的情況下工作,但要記住,它可能仍然是非常內存密集型,以在大圖運行。

更長遠的解決方案:重構圖和/或使用APOC

根據你的使用情況,更好或更長期的解決辦法是重構你的圖形來具體談談關係,以加快查詢時間當你想查找僅通過電子郵件或電話號碼鏈接的賬戶 - 即-[:ACCOUNT_HAS_EMAIL]--[:ACCOUNT_HAS_PHONE]-。然後,您可能還想使用APOC的shortest path algorithmspath finder functions,這將最有可能返回比使用密碼更快的結果,並且允許您更詳細地描述關係類型,因爲圖形擴展以獲取更多數據。

+1

感謝大教堂,這工作像魅力。我現在明白了我的Graph設計中的基本缺陷。我會糾正設計並嘗試APOC。以前從未嘗試過。再次感謝。 – Agandalf