경로 함수#

graphpath에 대한 함수들과, 그것을 만들어 내는 세 가지 경로 탐색 형태입니다. graphpath는 MATCH p = (...)가 바인딩하는, 정점과 간선이 번갈아 오는 나열입니다.

경로는 이름을 붙여 바인딩합니다. MATCH p = (a)-[r]->(b)처럼입니다. 이 함수들은 패턴이 아니라 그 변수를 받습니다.

예제는 예제 데이터셋에서 실행됩니다.

allshortestpaths#

allshortestpaths ( pattern ) -> graphpath

두 정점 사이의 모든 최단 경로를 찾습니다. 경로 변수에 이름을 붙이면 경로마다 한 행을 반환하고, 표현식으로 쓰면 경로의 배열을 반환합니다.

고려할 점

  • 패턴에는 관계가 정확히 하나 있어야 하며, 그렇지 않으면 파서가 only one relationship is allowed를 냅니다. 홉을 더 적는 대신 그 관계에 *..4 같은 길이 범위를 주십시오.

  • 여러 타입을 쓴 관계 패턴은 어디서도 지원되지 않으며 allshortestpaths도 그렇습니다. 타입 없는 간선을 일치시키고 WHERE label(r) IN [...]으로 걸러 내십시오.

  • 표현식으로 쓰면 graphpath[]를 내놓으므로, 그것에 대한 length()는 한 경로의 간선 수가 아니라 찾아낸 경로의 개수를 셉니다.

MATCH (a:movie {title:'The Matrix'}), (b:movie {title:'Inception'})
RETURN length(allshortestpaths((a)-[:related_to*..4]->(b))) AS paths_found;
 paths_found
-------------
 1

dijkstra#

dijkstra ( pattern, weight ) -> graphpath
dijkstra ( pattern, weight, condition ) -> graphpath
dijkstra ( pattern, weight, LIMIT count ) -> graphpath
dijkstra ( pattern, weight, condition, LIMIT count ) -> graphpath

두 정점 사이의 가장 값싼 경로를 찾습니다. 각 간선의 비용은 weight가 평가된 값입니다.

이름

타입

설명

pattern

경로 사슬

두 정점 사이의 관계 정확히 하나입니다. 예를 들어 (a)-[e:related_to]->(b)입니다. weight가 그 관계의 속성을 읽는다면 관계에 변수를 주십시오.

weight

수치 표현식

간선 하나를 지나는 비용입니다. 고려되는 모든 간선에서 0보다 커야 합니다.

condition

불리언 표현식

간선에 대한 선택적 필터입니다. 이것을 만족하는 간선만 지나갑니다.

count

정수

선택 사항입니다. 값싼 것부터 반환할 대안 경로의 개수입니다. 0보다 커야 합니다.

고려할 점

  • 패턴의 일부로 적으면 경로를 바인딩합니다. p = dijkstra(...)입니다. (p, w) = dijkstra(...)로 적으면 경로와 그 총 가중치를 바인딩하며, 그 값은 그 밖의 방법으로는 얻을 수 없습니다.

  • LIMIT이 없으면 개수의 기본값이 1이므로 경로 하나가 돌아옵니다.

  • 패턴은 속성 제약도, 가변 길이 관계도 받지 않습니다. 대신 WHERE에서 걸러 내십시오.

MATCH (a:movie {title:'The Matrix'}), (b:movie {title:'Inception'}),
      p = dijkstra((a:movie {title:'The Matrix'})-[e:related_to]->(b), e.weight)
RETURN p;
ERROR:  property constraint is not supported
LINE 2:       p = dijkstra((a:movie {title:'The Matrix'})-[e:related...
                            ^
MATCH (a:movie {title:'The Matrix'}), (b:movie {title:'Inception'}),
      p = dijkstra((a)-[e:related_to*]->(b), e.weight)
RETURN p;
ERROR:  variable length relationship is not supported
  • 세 번째 위치 인자는 조건이므로, 그 자리에 숫자를 두면 cannot cast 1 (jsonb type numeric) to boolean이 나옵니다.

  • 거부가 두 개 더 있는데 간선에 도달한 뒤 실행 시점에 나오므로, 쿼리만이 아니라 데이터에 달려 있습니다. 0 이하로 평가되는 가중치는 WEIGHT must be larger than 0을, LIMIT 0은 LIMIT must be larger than 0을 보고합니다.

  • 할당하지 않고 표현식으로만 쓰면 graphpath[]를 내놓습니다.

가장 값싼 경로가 가장 짧은 경로는 아닙니다. Total Recall을 지나는 두 홉의 비용은 4 + 2이고, 이 그래프에서는 그것이 한 홉 대안들을 이깁니다:

MATCH (a:movie {title:'The Matrix'}), (b:movie {title:'Inception'}),
      (p, w) = dijkstra((a)-[e:related_to]->(b), e.weight)
RETURN [x IN nodes(p) | x.title] AS route, w AS weight;
                    route                    | weight
---------------------------------------------+--------
 ["The Matrix", "Total Recall", "Inception"] | 6

먼 쪽 끝점을 제약하지 않으면 도달할 수 있는 모든 영화까지의 가장 값싼 경로가 나옵니다:

MATCH p = dijkstra((a:movie)-[e:related_to]->(b:movie), e.weight, LIMIT 1)
WHERE a.title = 'The Matrix'
RETURN [x IN nodes(p) | x.title] AS route ORDER BY route;
                                            route
---------------------------------------------------------------------------------------------
 ["The Matrix"]
 ["The Matrix", "The Matrix Reloaded"]
 ["The Matrix", "The Terminator"]
 ["The Matrix", "Total Recall"]
 ["The Matrix", "The Matrix Reloaded", "The Matrix Revolutions"]
 ["The Matrix", "The Terminator", "Terminator 2: Judgment Day"]
 ["The Matrix", "Total Recall", "Inception"]
 ["The Matrix", "The Matrix Reloaded", "The Matrix Revolutions", "The Matrix Resurrections"]

ORDER BY가 없으면 행은 특정한 순서 없이 돌아옵니다. 위의 정렬은 지면을 재현 가능하게 만들기 위한 것뿐입니다.

참고

dijkstra가 찾은 경로도 다른 것과 같은 graphpath이므로 nodes()·relationships()·length()가 모두 그것을 읽습니다. 다른 경로가 지니지 않는 것은 총 가중치이고, 그것을 드러내는 것은 (p, w) = 형태뿐입니다.

edges#

edges ( p graphpath ) -> edge[]

경로의 간선을 순서대로 반환합니다. relationships가 Cypher가 쓰는 이름으로 부른 같은 함수입니다.

end_vertex#

end_vertex ( e edge ) -> vertex

간선이 가리키는 정점을 반환합니다. endNode가 Cypher가 쓰는 이름으로 부른 같은 함수이며, 둘 다 스칼라 페이지에 나열돼 있습니다.

고려할 점

  • 정점을 읽는다는 것은 그 행을 가져온다는 뜻입니다. 식별자만으로 충분하다면 간선 자신의 컬럼을 읽는 end_id를 쓰십시오.

length#

length ( p graphpath ) -> jsonb
length ( vs vertex[] ) -> jsonb
length ( es edge[] ) -> jsonb
length ( ps graphpath[] ) -> jsonb

경로에 대해서는 그 안의 간선 수를, 배열에 대해서는 요소 수를 반환합니다.

고려할 점

  • 요소 수가 아니라 간선 수입니다. 간선 하나인 경로의 길이는 1이지만 같은 경로의 cardinality는 3입니다.

  • allshortestpaths()와 할당하지 않은 dijkstra()가 graphpath[]를 내놓으므로, 그런 것에 대한 length()는 경로의 개수를 셉니다.

  • 문자열·리스트·맵에 대한 length는 다른 함수입니다. 스칼라 페이지의 length를 참고하십시오.

MATCH (a:movie {title:'The Matrix'}), (b:movie {title:'The Matrix Resurrections'})
RETURN length(shortestpath((a)-[:related_to*]->(b))) AS hops;
 hops
------
 3

nodes#

nodes ( p graphpath ) -> vertex[]

경로의 정점을 순서대로 반환하며, 그 경로가 시작하는 정점부터 시작합니다.

고려할 점

  • 결과는 네이티브 배열인 vertex[]이므로 Cypher의 RETURN이 그것을 jsonb로 감싸지 않습니다. 첨자는 여전히 0부터입니다.

  • vertices가 다른 이름으로 부른 같은 함수입니다.

  • 경로 변수를 넘기십시오. 그 자리에 적은 패턴은 표현식이 아니어서 파싱되지 않습니다.

  • 정점 전체를 출력하는 것이 원하는 것인 경우는 드뭅니다. 하나하나가 자기 properties를 온전히 지니고 있기 때문입니다. 아래처럼 리스트 컴프리헨션으로 필요한 항목만 투영하십시오.

MATCH p=(:person {name:'Christopher Nolan'})-[:directed]->(:movie {title:'Inception'})
RETURN [x IN nodes(p) | x.name] AS names, [x IN nodes(p) | x.title] AS titles;
            names            |       titles
-----------------------------+---------------------
 ["Christopher Nolan", null] | [null, "Inception"]

경로의 모든 정점이 투영되므로, 어떤 정점이 지니고 있지 않은 키는 null로 돌아옵니다.

relationships#

relationships ( p graphpath ) -> edge[]

경로의 간선을 순서대로 반환합니다. edges와 동일합니다.

MATCH p=(:person {name:'Christopher Nolan'})-[:directed]->(:movie {title:'Inception'})
RETURN relationships(p) AS edges;
           edges
----------------------------
 [directed[6.8][4.8,3.5]{}]

shortestpath#

shortestpath ( pattern ) -> graphpath

두 정점 사이의 최단 경로 하나를 간선 수 기준으로 찾습니다. 똑같이 짧은 것이 여럿이면 그중 하나가 반환됩니다.

고려할 점

  • 패턴에는 관계가 정확히 하나 있어야 하고, 길이 범위는 그 관계가 지닙니다. 홉을 늘여 쓰는 것은 거부됩니다:

MATCH (a:movie {title:'The Matrix'}), (b:movie {title:'Inception'})
RETURN shortestpath((a)-[:related_to]->()-[:related_to]->(b));
ERROR:  only one relationship is allowed
LINE 2: RETURN shortestpath((a)-[:related_to]->()-[:related_to]->(b)...
                            ^
  • 똑같이 짧은 경로가 여럿일 때 어느 것을 받는지는 정해져 있지 않습니다. 전부 필요하면 allshortestpaths를 쓰십시오.

  • 경로가 없으면 null인 경로가 아니라 아무 행도 반환하지 않습니다.

  • 여러 타입을 쓴 관계 패턴은 여기서도 지원되지 않습니다.

MATCH (a:movie {title:'The Matrix'}), (b:movie {title:'The Matrix Resurrections'})
RETURN [x IN nodes(shortestpath((a)-[:related_to*]->(b))) | x.title] AS route;
                                            route
---------------------------------------------------------------------------------------------
 ["The Matrix", "The Matrix Reloaded", "The Matrix Revolutions", "The Matrix Resurrections"]

start_vertex#

start_vertex ( e edge ) -> vertex

간선이 떠나는 정점을 반환합니다. startNode가 Cypher가 쓰는 이름으로 부른 같은 함수입니다. startNode를 참고하십시오.

정점은 복합 타입이므로, 그 결과에서 속성을 곧바로 읽을 수 있습니다:

MATCH (:person {name:'Keanu Reeves'})-[e:acted_in]->(:movie {title:'The Matrix'})
RETURN start_vertex(e).name AS actor, end_vertex(e).title AS film;
     actor      |     film
----------------+--------------
 "Keanu Reeves" | "The Matrix"

vertices#

vertices ( p graphpath ) -> vertex[]

경로의 정점을 순서대로 반환합니다. nodes와 동일합니다.

호환성#

openCypher#

shortestPath와 allShortestPaths는 대소문자를 가리지 않고 표기되므로 openCypher의 대소문자 표기도 동작합니다. openCypher에는 dijkstra가 없습니다. 거기서 가중 최단 경로는 프로시저 라이브러리에서 옵니다.

openCypher는 -[r:acted_in|directed]->처럼 관계 패턴이 여러 타입을 이름으로 부르는 것을 허용합니다. 여기서 그것은 모든 길이에서, 모든 경로 탐색 형태 안에서 multiple types for relationship not supported를 냅니다. 대신 타입 없는 관계를 일치시키고 레이블을 검사하십시오:

MATCH (p:person)-[r]->(m:movie) WHERE label(r) IN ['acted_in','directed'] RETURN count(r) AS n;
 n
----
 46

관련 항목#