2014-10-20 2 views
0

Neo4j 2.1.4를 사용 중입니다. 노드 사이에 'IS A'관계 (및 다른 유형의 관계)가있는 그래프가 있습니다. 나는 그래프 내부에 몇 가지 계층 구조 (IS A 관계)가 있으며, 두 번째 계층 구조의 일부 자손과 특정 관계가있는 하나의 계층 구조의 자손 (IS A 관계)을 알아야합니다. 그 특정 - 알려진 관계가 존재하는 경우, 나는 첫 번째 계층의 자손을 반환합니다.Neo4j - 슬로우 사이퍼 쿼리 - 계층 구조가있는 큰 그래프

입력 : 'ID_parentnode_hierarchy_01', 'ID_relationship', 'ID_parentnode_hierarchy_02'.
OUTPUT : 'ID_parentnode_hierarchy_02'의 일부 자손과 'ID_relationship'이있는 'ID_parentnode_hierarchy_01'의 자손 (IS A 관계)입니다.

참고 : 그래프에는 500.000 개의 노드와 200 만 개의 관계가 있습니다.

이 사이퍼 쿼리를 사용하고 있지만 매우 느립니다 (4GB RAM 및 3GHz 펜티엄 듀얼 코어 64 비트 PC에서는 약 40 초). 빠른 쿼리를 작성할 수 있습니까?

MATCH (parentnode_hierarchy_01: Node{nodeid : {ID_parentnode_hierarchy_01}}) 
WITH parentnode_hierarchy_01 
MATCH (parentnode_hierarchy_01) <- [:REL* {reltype: {isA}}] - (descendants01: Node) 
WITH descendants01 
MATCH (descendants01) - [:REL {reltype: {ID_relationship}}] -> (descendants02: Node) 
WITH descendants02, descendants01 
MATCH (parentnode_hierarchy_02: Node {nodeid: {ID_parentnode_hierarchy_02} }) 
<- [:REL* {reltype: {isA}}] - (descendants02) 
RETURN DISTINCT descendants01; 

고맙습니다.

+0

가능한 경우 일반 relationshiptypes 및 rel-property는 사용하지 마십시오. 그러면 쿼리 속도가 느려질 것입니다. –

+0

CSV 파일에서 'LOAD CSV WITH HEADERS FROM ...'및 '... CREATE (c1) - [: REL {reltype : rel.relid, reldesc : rel.desc}] -> (c2) '. 관계의 유형으로 'rel.relid'(CSV 파일에서)를 설정하는 방법을 모르겠습니다. 그래서 일반 REL 관계를 사용합니다. 감사. – Vicente

답변

1

음, 약간 쿼리를 정리할 수 있습니다. 이렇게하면 문제를 더 잘 이해하는 데 도움이 될 수 있습니다. 나는이 하나의 실행 속도를 의심하지만, 청소 버전을 사용하여 우리는 무슨 일이 일어나고 있는지 논의 할 수

MATCH (parent:Node {nodeid: {ID_parentnode_hierarchy_01}})<-[:REL* {reltype:{isA}}]- 
     (descendants01:Node)-[:REL {reltype:{ID_relationship}}]->(descendants02:Node), 

     (parent2:Node {nodeid: {ID_parentnode_hierarchy_02}})<-[:REL* {reltype:{isA}}]- 
     (descendants02) 
RETURN distinct descendants01; 

당신이 검색하는 것처럼이 보인다 (대부분 MATCH/WITH의 불필요한 사용을 제거)이 (아마도 대형) {ID_relationship}에 의해 링크 된 나무 어딘가의 두 노드에 대한 루트에서 시작하는 트리.

트리의 어느 노드에 ID_relationship 또는 그와 비슷한 것을 묻는 쿼리 힌트를 제공 할 수 없다면, 최악의 경우 두 트리의 두 노드를 모두 비교할 수있는 것처럼 보입니다. 그래서 이것은 n * k 시간이 걸릴 수있는 것처럼 보입니다. 여기서 n은 첫 번째 트리의 노드 수이고, k는 두 번째 트리의 노드 수입니다.

  1. 이 링크가 가능성이 트리에서 약간의 깊이가 있는가가

    를 찾을 수 : 당신이 사용해야하는 귀하의 데이터에 의존 - 여기

    대해 생각하는 몇 가지 전략 일입니까? [:REL* {reltype:{isA}}]의 깊이 범위를 넣을 수 있습니까?
  2. descendants01descendants02에 추가 할 수있는 다른 기준은 무엇입니까? 한 트리의 모든 노드를 다른 노드의 모든 노드와 비교하지 않도록 쿼리를보다 선택적으로 만들 수있는 방법이 있습니까? (이 끔찍한 생각이 될 수도 있지만 노력의 가치) - 기본적으로 하나 isa의 방향성 모서리의 수를 통해, 다른 하나 개의 루트에서 경로를 찾아 : 당신이 시도 할 수

또 다른 전략은 이것이다 유형, 또는 다른. 귀하의 데이터 모델은 reltype 속성을 가진 :REL 관계가 있습니다. 이것은 아마도 반 패턴입니다. reltype 속성 대신 관계 유형이 왜 그런가요?당신이 원하는 다리를 통해,

MATCH p=shortestPath((p1:Node {nodeid: {first_parent_id}})-[:isA|ID_relationship*]-(p2:Node {nodeid: {second_parent_id}})) 
return p; 

이 다른 하나의 "루트"에서 경로를 반환 : 이것은 내가 아래, 쓰고 싶은 쿼리를 방지 할 수 있습니다. 그런 다음 경로 함수를 사용하여 원하는 노드를 추출 할 수 있습니다. 이 쿼리는 현재 데이터 모델 때문에 가능하지 않습니다.