2014-02-24 3 views
0

이것은 다른 SO (Neo4j 2.0 Merge with unique constraints performance bug?)의 확장이지만 다른 방식으로 시도하고 있습니다.Neo4j에서 노드를 반복하고 관계를 만들 때

MATCH (c:Contact),(a:Address), (ca:ContactAddress) 
WITH c,a,collect(ca) as matrix 
FOREACH (car in matrix | 
MERGE 
(c {ContactId:car.ContactId}) 
-[r:CONTACT_ADDRESS {ContactId:car.ContactId,AddressId:car.AddressId}]-> 
(a {AddressId:car.AddressId})) 

이렇게하면 잠긴 Neo4j 서버가됩니다. 나는 왜 내 머리를 싸려고 노력하고있다. 쿼리 뒤에
내 생각의 과정은 다음

  • 내가 관계를 포함하는 모든 ContactAddress 노드를 통해
  • 내가 루프를 원하는 모든 연락처 및 주소 노드 (뿐만 아니라 ContactAddress 노드)를 (선택합니다 연락처와 주소 사이의 데이터)와 접촉 및 주소 노드를 서로 연관시킵니다.

위 코드를 실행하면 서버가 약 40 %의 CPU에 위치하여 메모리가 계속 올라갑니다. 다음 사용하여,이 시간, 내 데이터베이스를 재설정하고 다시 시도 :

match (c:Contact),(a:Address), (ca:ContactAddress) 
WITH c,a,collect(distinct ca) as matrix 
foreach (car in matrix | 
CREATE 
(c {ContactId:car.ContactId}) 
-[r:CONTACT_ADDRESS {ContactId:car.ContactId,AddressId:car.AddressId}]-> 
(a {AddressId:car.AddressId})) 

같은 결과를 (7474/브라우저에서 myserver) 나는 분리를 연결 브라우저 후를 중단했다. CPU가 고정되어 있고 RAM 사용량이 계속 올라가는 동안 잠금, 연결 해제 된 Neo4j 데이터베이스. 내가 여기 보지 않을 루프가 있나?

FOREACH(row in {PassedInList} | 
    MERGE (c:Contact {ContactId:row.ContactId}) 
    MERGE (a:Address {AddressId:row.AddressId}) 
    MERGE (c)-[r:CONTACT_ADDRESS]->(a) 
    ) 

가 해결 :

가 나는 또한 (멈춤 같은과)이 시도했습니다

MATCH (ca:ContactAddress) 
MATCH (c:Contact {ContactId:ca.ContactId}), (a:Address {AddressId:ca.AddressId}) 
MERGE p = (c) 
      -[r:CONTACT_ADDRESS {ContactId:ca.ContactId,AddressId:ca.AddressId}]-> 
      (a) 

답변

3

당신이 match (c:Contact),(a:Address), (ca:ContactAddress)을 쓸 때, 3 개 끊어 노드와 다음 Neo4j는 일치합니다 각각의 가능한 모든 직교 곱입니다. 3. 각 노드 유형이 100 개인 경우 100x100x100 = 1000000 결과입니다.

MATCH (ca:ContactAddress), (c:Contact {ContactId:ca.ContactId}), (a:Address {AddressId:ca.AddressId}) 
MERGE (c)-[r:CONTACT_ADDRESS {ContactId:ca.ContactId,AddressId:ca.AddressId}]->(a) 

모든 :ContactAddress 노드와 일치하는 것으로하고, 일치하는 경우에만 :Contact:Address 노드 :

이 시도해보십시오. 그런 다음 관계를 만듭니다 (아직 존재하지 않은 경우).

MATCH (ca:ContactAddress) 
MATCH (c:Contact {ContactId:ca.ContactId}), (a:Address {AddressId:ca.AddressId}) 
MERGE (c)-[r:CONTACT_ADDRESS {ContactId:ca.ContactId,AddressId:ca.AddressId}]->(a) 
+0

아, 흥미로운 :

당신이 명확하게하려면

은 또한 MATCH, 즉 분할 할 수있다. 나는 항상 그들이 모든 접촉 노드, 모든 주소 노드 및 모든 접촉 주소 노드를주고 나서 각각 독립적으로 처리하는 것과 같은 독립적 인 성냥이라고 생각했습니다. 나는 그것이 효과가 있다면 추천하고보고 싶은 것을 시도 할 것입니다 (그리고 여기에 다시 올릴 것입니다). 감사! – dcinzona

+0

match 문이 작동합니다 (서버를 넘겨주지 않는 경우와 같습니다 :) MERGE에 대해서는 foreach 내부에서 MERGE를 사용한다고 가정합니다. 각 forEach 변수는 'car'변수를 반복기로 사용하기 때문입니다. – dcinzona

+0

DUDE, 넌 정말 대단해. 이것은 효과적 일뿐만 아니라 효과적 일뿐만 아니라 매우 효율적으로 처리되었습니다 (모든 것을 처리하는 데 5 초). 이제 시스템에 ContactAddress 행렬을 삽입하지 않고 수행 할 수 있는지 확인하십시오. 가능하지 않을 수 있습니다. 나는이 답에 더 많은 표를 더할 수 있었으면 좋겠다. 위에 편집 된 최종 쿼리입니다. – dcinzona

관련 문제