2016-06-16 3 views
2

경로 사이에서 특정 노드 레이블 경로 주소 및 : 마일스톤 (각 노드에 하나)Neo4j 최단 나는 다음과 같은 문제를 해결하기위한 힌트를 찾고 있어요

서로 다른 노드 사이에는 LEADS_TO 관계가 있습니다.

주어진 다음의 패턴 (필자는 []의 관계에 대한 생략) :

패턴 1 :

(a:Address)->(:Milestone)->(:Milestone)<-(:Milestone)<-(:Milestone)<-(b:Address) 

패턴 2 :

(a:Address)->(:Milestone)->(c:Address)<-(:Milestone)<-(b:Address) 

제가 쿼리를 찾고 있어요를 최단 경로 분석에서 동일한 유형의 "중간"노드 만 포함합니다. 필자의 경우에는 레이블이있는 노드 (예 : 중요 시점) 만 포함해야하며 더 짧은 경로는 건너 뜁니다.

즉, 검색어가 패턴 1보다 짧고 패턴 2와 일치해야합니다.

MATCH p=shortestPath((a:Address)-[:LEADS_TO*..10]-(b:Address)) 
WHERE a.name = 'XYZ' 
AND b.name = 'ABC' 
AND ALL(x IN nodes(p) WHERE (x:MILESTONE)) 
RETURN p 

내 초기 아이디어가 있었다 :

나는 가깝게하지만 그것뿐만 아니라 시작과 끝 노드 레이블을 설명하고이 때문에 전혀 행을 선택하지 않기 때문에 내 경우에는 실패 다음 해결책을 발견 시작 노드

MATCH (a:Address)-[:LEADS_TO]->(aa:Milestone) 

를 들어

및 엔드 노드와 유사하고 거기에서 쿼리를 시작하는 제 1 홉을 만들 수 있습니다.

그러나 이것은 모든 문제가 있습니다. 주소 노드가 여러 개의 : LEADS_TO 관계를 가질 수 있기 때문입니다. 정의 된 시작 및 종료 노드에 대한 최단 경로를 조회하면이 접근법은 별개의 시작 및 끝 노드로 실행될 수있는 하나의 쿼리에 대해 n 개의 시작 노드 및 m 개의 끝 노드를 작성합니다.

누구나 Cypher 내의 WHERE 절에서 시작 및 끝 노드를 제외하는 방법에 대한 아이디어가 있습니까?

모든 의견을 크게 환영합니다.

답변

3

이 시도, 당신은 슬라이스 연산자 어떤 필터를 사용하는 방법에 대한()이 같은

MATCH p=shortestPath((a:Address)-[:LEADS_TO*..10]-(b:Address)) 
WHERE a.name = 'XYZ' 
AND b.name = 'ABC' 
AND ALL(x IN nodes(p)[1..-1] WHERE (x:MILESTONE)) 
RETURN p 
+0

감사합니다. Michael, 벤치 마크를 수행했으며이 작업이 더 빠릅니다. – Krid

2

당신은 관계의 유형에 따라 WHERE ALL 절을 사용할 수 있으며 노드는 예를 들어, 시작 또는 끝없는 : 도움을

MATCH p=shortestPath((a:Address)-[:LEADS_TO*..10]-(b:Address)) 
WHERE a.name = 'XYZ' 
AND b.name = 'ABC' 
AND ALL(x IN range(1, size(nodes(p)-2)) 
     WHERE 'Milestone' IN labels(nodes(p)[x])) 
0

감사합니다. 그것은 약간의 수정과 함께 일했습니다. 반환 된 노드 내의 크기 계산이 올바른지 확인하기 위해 두 개의 괄호 (size 메서드를 중심으로)를 두 개 추가해야했습니다.

MATCH p=shortestPath((a:Address)-[:LEADS_TO*..10]-(b:Address)) 
WHERE a.name = 'XYZ' 
AND b.name = 'ABC' 
AND ALL(x IN range(1, (size(nodes(p))-2)) 
    WHERE 'Milestone' IN labels(nodes(p)[x])) 

초기 일치 방식보다 확실히 빠릅니다.

MATCH p=shortestPath((a:Address)-[:LEADS_TO*..10]-(b:Address)) 
WHERE a.name = 'XYZ' 
AND b.name = 'ABC' 
RETURN FILTER(x IN nodes(p) WHERE 'Milestone' IN labels(x)) 

그것은 당신에게 모든 마일스톤 노드를 반환합니다

0

와 컬렉션의 일부를 사용할 수 있습니다.

관련 문제