2014-04-04 3 views
1

나는 두 번째 부분으로 I asked elsewhere이라는 질문을 펼칩니다.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) 

을 사용하고 있었다 그리고 나는 새/독특한/원하는 동안 [: FRIENDS] 관계를 노드가 이미하지 않는 경우, 나는 새로운 사용자 나 새로운 친구를 만들고 싶지 않아 유효한 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)" 

는 고유은 this answer이가 수정되었습니다 제안에도 불구하고, FOREACH 구조 지원하지 않는 것 만들기입니다.

또한 추가 노드를 만들지 않으므로 here in 11.2.2이라는 제안 구문을 사용할 수 없으며 기존 노드와의 새로운 관계 만 만들 수 있습니다. 문제의

답변

2

커플 :

첫째, 그것은 CREATE UNIQUE 패턴 사용자와 친구 노드 주위 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 가지를 바람직하지 않게 만들었고, 새로운 (친구)를 만들었고 친구의 각 친구에 대한 연결 대신에 단지 하나의 연결만을 만들었습니다. 그래서 당신이 말했던 것처럼 친구 식별자가 행동한다고 ​​생각하지 않습니다. 병합의 결과 그래프에 이미있는 X (알려진) 친구 (친구)와 1 명 (사용자)이 아닌 그래프에없는 새로 만든 친구 (친구)와 (사용자) 사이의 단일 연결이 이루어졌습니다. – Mittenchops

관련 문제