2014-04-04 70 views
1

我將第列爲第二部分。在neo4j中創建唯一關係而不創建唯一節點

對於一個已知id_str已知在圖中的給定節點,我有一個新的id_str列表,這些列表可能包含或不包含在圖中。如果他們/在圖中,我想與他們建立獨特的關係。 (如果它們不是,我想忽略它們)。

我現在的方法很慢。我正在做Neo之外的循環部分,使用py2neo並使用非常慢的過濾器逐個寫入條目。

本來,我是用...

fids = get_fids(record) # [100001, 100002, 100003, ... etc] 
ids_in_my_graph = filter(id_is_in_graph, fids) # [100002] 

def id_is_in_graph(id): 
    val = False 
    query = """MATCH (user:User {{id_str:"{}"}}) 
    RETURN user 
    """.format(id) 
    n=neo4j.CypherQuery(graph_db,query).execute_one() 
    if n: 
     val = True 
    return(val) 

for i in ids_in_my_graph: 
    """MATCH (user:User {{id_str:"{}"}}),(friend:User {{id_str:"{}"}}) 
     WHERE has(user.id_str) AND has(friend.id_str) 
     CREATE UNIQUE (user)-[:FRIENDS]->(friend)""".format(record.id, i) 

雖然我希望新的/獨特/ [:朋友]的關係,我不希望創建新的用戶或者新朋友如果一個節點已經不存在一個有效的id_str。

所以,我試圖用集合中的FOREACH來重寫這個。我認爲實際的語法會...

MATCH (user:User {id_str:"200001"}), (friends:User) 
WHERE friends.id_str IN ["100001", "100002", "100003", "JUNK", "DOESNTMATCH", "IGNORED"] 
FOREACH(friend in friends : 
CREATE UNIQUE user -[:FRIENDS]-> friend) 

但我的錯誤是

py2neo.neo4j.SyntaxException: Invalid input 'U': expected whitespace, comment, NodeLabel, MapLiteral, a parameter, a relationship pattern, '.', node labels, '[', "=~", IN, IS, '*', '/', '%', '^', '+', '-', '<', '>', "<=", ">=", '=', "<>", "!=", AND, XOR, OR or '|' (line 3, column 48) 
"   FOREACH(friend in friends : CREATE UNIQUE user -[:FRIENDS]-> friend)" 

創造出獨特的似乎並不被支持foreach構造,即使this answer表明,這已得到修復。

再次,我不能使用語法建議here in 11.2.2,因爲我不想要創建額外的節點,只有與已有節點的新關係。

回答

2

兩個問題:

首先,將要圍繞在CREATE獨特的模式在用戶與朋友節點parenthesises。其次,FOREACH內部的「:」分隔符已被更改爲「|」,因爲與用於類型和標籤的「:」存在可讀性衝突。

第三,您應該使用MERGE而不是創建唯一的。它更快,更可預測,它取代了CREATE UNIQUE。

最後:

從概念上講,「朋友」標識符指向一個朋友「在同一時間」,可以這麼說,它是不是所有的朋友的集合。您可以通過把它變成這樣:

WITH user, COLLECT(friends) AS friends 

當然,你可能已經猜到,這實際上意味着你不需要在foreach可言,所以你的最終查詢可能是:

MATCH (user:User {id_str:"200001"}), (friend:User) 
WHERE friend.id_str IN ["100001", "100002", "100003", "JUNK", "DOESNTMATCH", "IGNORED"] 
MERGE (user) -[:FRIENDS]-> (friend) 

確保你有一個在friend.id_str上定義的索引,否則這將會非常緩慢:)

+0

MERGE是否保持關係的唯一性?如果我運行兩次,我不會在(a)和(b)之間獲得第二個[:FRIENDS]關係? – Mittenchops

+0

不,這正是我不想要的 - 它創造了圖中不存在的新(朋友)。該死。=( – Mittenchops

+0

其實,它做了2件不可取的事情,它創建了一個新的(朋友),它也只做了1個連接,而不是朋友中每個朋友的連接,所以我不認爲朋友標識符的行爲如你所說。合併的結果是(用戶)和一個新創建的(朋友)之間的單個連接,這個連接不在圖中,而不是1(用戶)連接到已經在圖中的已知X(朋友)。 – Mittenchops