2013-06-17 3 views
1

매우 간단한 그래프가 있습니다. 약 100 개의 노드와 400 개의 관계 만 있습니다. 특정 관계의 존재 여부에 따라 결과의 순위를 매기는 다양한 사이퍼 쿼리를 실행하려고합니다. 그러나 작은 데이터베이스에서도 이러한 쿼리가 시간 초과됩니다. 누구든지 시간 초과를 일으키는 내 쿼리의 문제를 식별 할 수 있습니까?가중치가있는 복잡한 쿼리의 Cypher 쿼리 제한 시간

아래의 쿼리는 다양한 패턴을 검색합니다. 패턴이 존재하면 관계에 가중치를 적용합니다. 마지막에는 가중치를 결합하고 결과를 순위 지정하여 가장 중요한 가중치가있는 노드 (가장 중요한 관계)가 우선 순위가 부여됩니다.

START node=node(1) 
MATCH (node)-[a?:REQUIRES]-(thing0)-[?:RELATED]-(stuff) 
,(node)-[b?:REQUIRES]-(thing1)-[:RELATED]-(system1)-[:COMPOSITION]-(something1)-[?:VERSION]-(stuff) 
,(node)-[c?:REQUIRES]-(thing2)-[:RELATED]-(something2)-[?:VERSION]-(stuff) 
,(node)-[d?:REQUIRES]-(thing3)-[:REQUIRES]-(project1)-[:REQUIRES]-(thing6)-[?:RELATED]-(stuff) 
,(node)-[e?:REQUIRES]-(thing4)-[:DESCRIBES]-(part)-[:DESCRIBES]-(thing5)-[?:RELATED]-(stuff) 
WITH stuff 
, count(distinct a)*.15 as shareA 
, count(distinct b)*.35 as shareB 
, count(distinct c)*.25 as shareC 
, count(distinct d)*.10 as shareD 
, count(distinct e)*.15 as shareE 
WHERE has(stuff.__type__) 
AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = shareA + shareB + shareC + shareD + shareE 
RETURN DISTINCT stuff 
ORDER BY stuff.weight DESC 
+0

나는 적절한 대답을 할 시간이 없지만 선택적인 관계 성냥은 종종 느려지는 원인이됩니다. 가능하다면 선택적 관계를 사용할 필요가 없으므로'WITH'로 분할 해 볼 수도 있습니다. 돌아 오는 것을보기 위해'프로필 '을 해봤습니까? –

+0

저는 Neo4j를 처음 사용합니다. "프로필을 완성 했나요?"라는 의미를 설명 할 수 있습니다. – Blaine

+0

또한 "WITH"를 사용하여 쿼리를 다시 작성할 수 있는지 잘 모르겠습니다. 각 패턴은 실제로 선택 사항입니다. WITH는 모든 패턴과 일치하는 노드 만 포함하도록 결과 집합을 제한한다고 믿습니다. – Blaine

답변

1

여러분은 옵션을 제거하고 하나의 BATCH 요청 또는 트랜잭션 내부의 몇 가지 cypher 문에서 수행 할 수 있습니다.

START stuff=node(*) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = 0.0; 

START node=node(1) 
MATCH (node)-[a:REQUIRES]-(thing)-[:RELATED]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT a)*.15; 

START node=node(1) 
MATCH (node)-[b:REQUIRES]-(thing)-[:RELATED]-(system1)-[:COMPOSITION]-(something1)-[:VERSION]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT b)*.35 

START node=node(1) 
MATCH (node)-[c:REQUIRES]-(thing2)-[:RELATED]-(something2)-[:VERSION]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT c)*.25 

START node=node(1) 
MATCH (node)-[d:REQUIRES]-(thing3)-[:REQUIRES]-(project1)-[:REQUIRES]-(thing6)-[:RELATED]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT d)*.10 

START node=node(1) 
MATCH (node)-[e:REQUIRES]-(thing4)-[:DESCRIBES]-(part)-[:DESCRIBES]-(thing5)-[:RELATED]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT e)*.15 

START stuff=node(*) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
RETURN DISTINCT stuff 
ORDER BY stuff.weight DESC 

"WITH"로 모두 연결할 수는 있지만 상당히 복잡합니다.

+0

해결책이 효과적입니다. 그러나 노드에 가중치를 저장하지 않도록 가중치 적용 방식을 변경하려고했습니다. 여러 사용자가 유사한 쿼리를 실행하는 경우 이로 인해 동시성 문제가 발생할 수 있습니다. 사이퍼가 이러한 유형의 쿼리를 처리 할 수 ​​없다는 사실에 놀랐습니다. – Blaine

+0

이러한 쿼리를 "WITH"로 연결하면 제한 시간도 발생합니다. 나는 이들 각각을 병렬로 실행하는 수십 가지의 질의를 개발했기 때문에 모든 것을 분리하기를 주저한다. 위에서 언급했듯이 노드에 가중치를 저장하면 문제가 발생합니다. 이 쿼리는 작은 그래프로 잘 돌아갔다. 복잡한 관계를 처리 할 수없는 경우 그래프 데이터베이스에 값이 표시되지 않습니다. 관계형 데이터베이스는 이것을 훨씬 효율적으로 처리했을 것입니다. – Blaine

+0

문제는 선택적인 관계가 쿼리를 날려 버리는 것입니다. 우리가 그것으로 놀 수 있도록 zip graph.db 폴더를 어딘가에 게시 할 수 있습니까? –