이 페이지에서는 Spanner Graph에서 그래프 경로를 사용하는 방법을 설명합니다.
그래프 데이터베이스에서 그래프 경로 데이터 유형은 에지로 삽입된 노드의 시퀀스를 나타내며 이러한 노드와 에지의 관계를 보여줍니다. 경로 데이터 유형에 관한 자세한 내용은 그래프 경로 유형을 참고하세요.
Spanner Graph 언어 (GQL)를 사용하면 그래프 경로를 구성하고 이에 대해 쿼리를 실행할 수 있습니다. 이 문서의 예에서는 Spanner Graph 설정 및 쿼리 페이지에 있는 것과 동일한 Spanner Graph 스키마를 사용합니다.
그래프 경로 구성
그래프 패턴에서 또는 PATH
함수를 사용하여 경로 변수를 만들어 그래프 경로를 구성할 수 있습니다.
경로 변수를 사용하여 그래프 경로를 구성하는 것이 좋습니다. 경로 변수를 만드는 형식은 다음과 같습니다.
MATCH p = PATH_PATTERN
자세한 내용은 그래프 패턴을 참고하세요.
예시
다음 예에서는 쿼리가 FinGraph
내 계정 간의 송금 패턴을 찾습니다.
GRAPH FinGraph
MATCH p = (src:Account {id: 16})-[t1:Transfers]->(mid:Account)-[t2:Transfers]->
(dst:Account {id: 7})
RETURN TO_JSON(p) AS full_path;
결과
full_path |
---|
[{"identifier": ..., "properties": {"id": 16, ...}, ...}, {"identifier": ..., "properties": {"amount": 300.0, ...}, ...}, ...] |
이 결과는 쿼리가 데이터베이스에서 Account -> Transfers -> Account
패턴을 찾았음을 나타냅니다.
그래프 경로 쿼리
다음 경로별 함수를 사용하여 그래프 경로를 쿼리할 수 있습니다. Spanner Graph 쿼리에 관한 일반적인 정보는 쿼리 개요를 참고하세요.
EDGES
EDGES
함수는 그래프 경로의 모든 에지를 반환합니다. 자세한 시맨틱은 EDGES
를 참고하세요.
예시
이 쿼리는 중간 계정을 통과하는 두 계정 간의 경로를 찾습니다.
경로에서 두 번째 Transfers
가장자리의 크기를 반환합니다. 이 크기는 src
과 mid
사이 또는 mid
과 dst
사이일 수 있습니다.
GRAPH FinGraph
MATCH p = (src:Account {id: 7})-[t1:Transfers]->{1,3}(mid:Account)-[t2:Transfers]->
{1,3}(dst:Account {id: 16})
LET second_edge = EDGES(p)[1]
RETURN DISTINCT src.id AS src, dst.id AS dst, second_edge.amount AS second_edge_amount;
결과
src | dst | second_edge_amount |
---|---|---|
7 | 16 | 300 |
NODES
NODES
함수는 그래프 경로의 모든 노드를 반환합니다. 자세한 시맨틱은 NODES
를 참고하세요.
예시
이 쿼리는 두 전송의 그래프 경로를 찾은 다음 경로를 나타내는 JSON 목록을 반환합니다.
GRAPH FinGraph
MATCH p = (src:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(dst:Account)
RETURN TO_JSON(NODES(p)) AS nodes;
결과
nodes |
---|
[{"identifier": "...", "properties": {"id": 16}, ...}, {"identifier": "...", "properties": {"id": 20, ...}, ...] |
... |
PATH_FIRST
PATH_FIRST
함수는 그래프 경로에서 첫 번째 노드를 찾습니다. 자세한 시맨틱은 PATH_FIRST
를 참고하세요.
예시
이 쿼리는 두 전송의 그래프 경로에서 첫 번째 노드를 찾습니다. Account
노드의 라벨과 계정의 닉네임을 반환합니다.
GRAPH FinGraph
MATCH p = -[:Transfers]->{1,3}(dst:Account{id: 7})
RETURN DISTINCT PATH_FIRST(p).id AS can_reach_target;
결과
can_reach_target |
---|
7 |
16 |
20 |
PATH_LAST
PATH_LAST
함수는 그래프 경로의 마지막 노드를 찾습니다. 자세한 시맨틱은 PATH_LAST
를 참고하세요.
예시
이 쿼리는 두 전송의 그래프 경로에서 마지막 노드를 찾습니다. Account
노드의 라벨과 계정의 닉네임을 반환합니다.
GRAPH FinGraph
MATCH p =(start:Account{id: 7})-[:Transfers]->{1,3}
RETURN DISTINCT PATH_LAST(p).id as can_reach_target;
결과
can_reach_target |
---|
7 |
16 |
20 |
PATH_LENGTH
PATH_LENGTH
함수는 그래프 경로의 가장자리 수를 찾습니다. 자세한 시맨틱스는 PATH_LENGTH
를 참고하세요.
예시
이 쿼리는 1~3개의 전송이 포함된 그래프 경로의 에지 수를 찾습니다.
GRAPH FinGraph
MATCH p = (src:Account)-[e:Transfers]->{1,3}(dst:Account)
RETURN PATH_LENGTH(p) AS num_transfers, COUNT(*) AS num_paths;
결과
num_transfers | num_paths |
---|---|
1 | 5 |
2 | 7 |
3 | 11 |
IS_ACYCLIC
IS_ACYCLIC
함수는 그래프 경로에 반복 노드가 있는지 확인합니다. 반복이 발견되면 TRUE
를 반환하고, 그렇지 않으면 FALSE
를 반환합니다. 자세한 시맨틱은 IS_ACYCLIC
를 참고하세요.
예시
이 쿼리는 이 그래프 경로에 반복되는 노드가 있는지 확인합니다.
GRAPH FinGraph
MATCH p = (src:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(dst:Account)
RETURN IS_ACYCLIC(p) AS is_acyclic_path, src.id AS source_account_id,
mid.id AS mid_account_id, dst.id AS dst_account_id;
결과
is_acyclic_path | source_account_id | mid_account_id | dst_account_id |
---|---|---|---|
TRUE | 16 | 20 | 7 |
TRUE | 20 | 7 | 16 |
TRUE | 20 | 7 | 16 |
FALSE | 16 | 20 | 16 |
TRUE | 7 | 16 | 20 |
TRUE | 7 | 16 | 20 |
FALSE | 20 | 16 | 20 |
IS_TRAIL
IS_TRAIL
함수는 그래프 경로에 반복되는 가장자리가 있는지 확인합니다. 반복이 발견되면 TRUE
를 반환하고, 그렇지 않으면 FALSE
를 반환합니다. 자세한 시맨틱은 IS_TRAIL
를 참고하세요.
예시
이 쿼리는 이 그래프 경로에 반복되는 가장자리가 있는지 확인합니다.
GRAPH FinGraph
MATCH p = (src:Account)-[t1:Transfers]->(mid1:Account)-[t2:Transfers]->
(mid2:Account)-[t3:Transfers]->(dst:Account)
WHERE src.id < dst.id
RETURN IS_TRAIL(p) AS is_trail_path, t1.id AS t1_id, t2.id AS t2_id, t3.id AS t3_id;
결과
is_trail_path | t1_id | t2_id | t3_id |
---|---|---|---|
FALSE | 16 | 20 | 16 |
TRUE | 7 | 16 | 20 |
TRUE | 7 | 16 | 20 |
경로 모드
Spanner Graph에서 기본적으로 반복 노드와 에지가 반환됩니다. 다음 경로 모드를 사용하여 지정된 모드에 따라 노드와 가장자리가 반복되는 경로를 포함하거나 제외할 수 있습니다. 자세한 시맨틱은 경로 모드를 참고하세요.
WALK
기본 WALK
경로 모드는 반복되는 노드와 가장자리가 있는 경로를 포함한 모든 경로를 유지합니다.
예시
다음 쿼리는 수치화되지 않은 경로 패턴에서 WALK
경로 모드를 사용하는 방법을 보여줍니다. 결과의 첫 번째 경로는 t1
와 t3
에 동일한 가장자리를 사용합니다.
GRAPH FinGraph
MATCH p = WALK (src:Account)-[t1:Transfers]->(mid1:Account)-[t2:Transfers]->
(mid2:Account)-[t3:Transfers]->(dst:Account)
WHERE src.id < dst.id
RETURN t1.id AS transfer1_id, t2.id AS transfer2_id, t3.id AS transfer3_id;
결과
transfer1_id | transfer2_id | transfer3_id |
---|---|---|
16 | 20 | 16 |
7 | 16 | 20 |
7 | 16 | 20 |
ACYCLIC
기본 ACYCLIC
경로 모드는 반복되는 노드가 있는 경로를 필터링합니다.
예시
다음 쿼리는 수치화되지 않은 경로 패턴에서 ACYCLIC
경로 모드를 사용하는 방법을 보여줍니다.
src
및 dst
노드가 동일한 경로가 필터링됩니다.
GRAPH FinGraph
MATCH p = ACYCLIC (src:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(dst:Account)
RETURN src.id AS account1_id, mid.id AS account2_id, dst.id AS account3_id;
결과
account1_id | account2_id | account3_id |
---|---|---|
20 | 7 | 16 |
20 | 7 | 16 |
7 | 16 | 20 |
7 | 16 | 20 |
16 | 20 | 7 |
TRAIL
기본 TRAIL
경로 모드는 반복되는 가장자리가 있는 경로를 필터링합니다.
예시
다음 쿼리는 수치화되지 않은 경로 패턴에서 TRAIL
경로 모드를 사용하는 방법을 보여줍니다. t1
및 t3
가장자리가 동일한 경로는 필터링됩니다.
GRAPH FinGraph
MATCH p = TRAIL (src:Account)-[t1:Transfers]->(mid1:Account)-[t2:Transfers]->
(mid2:Account)-[t3:Transfers]->(dst:Account)
RETURN
t1.id AS transfer1_id, t2.id AS transfer2_id, t3.id AS transfer3_id;
결과
transfer1_id | transfer2_id | transfer3_id |
---|---|---|
16 | 20 | 7 |
16 | 20 | 7 |
20 | 7 | 16 |
20 | 7 | 16 |
7 | 16 | 20 |
7 | 16 | 20 |
7 | 16 | 20 |
7 | 16 | 20 |
20 | 16 | 20 |
경로 검색 프리픽스
경로 검색 접두사를 사용하여 경로 패턴을 제한하여 각 데이터 파티션에서 가장 짧은 경로를 반환할 수 있습니다. 자세한 시맨틱스는 경로 검색 접두사를 참고하세요.
ANY SHORTEST
ANY SHORTEST
경로 검색 접두사는 각 데이터 파티션의 패턴과 일치하는 가장 짧은 경로 (가장 적은 수의 간선이 있는 경로)를 반환합니다. 파티션당 최단 경로가 두 개 이상인 경우 그중 하나를 반환합니다.
예시
다음 쿼리는 각 [a, b]
쌍 간의 모든 경로를 일치시킵니다.
GRAPH FinGraph
MATCH p = ANY SHORTEST (a:Account)-[t:Transfers]->{1,4}(b:Account)
WHERE a.is_blocked
LET total_amount = SUM(t.amount)
RETURN a.id AS account1_id, total_amount, b.id AS account2_id;
결과
account1_id | total_amount | account2_id |
---|---|---|
16 | 500 | 16 |
16 | 800 | 7 |
16 | 300 | 20 |
변환 규칙
자세한 내용은 GRAPH_PATH 변환 규칙을 참고하세요.
사용 사례 예시
다음 사용 사례 예에서는 모든 계정이 계정 ID 20
에서 1~3개의 계정을 통해 라우팅된 것을 확인할 수 있습니다.
GRAPH FinGraph
MATCH p = (start:Account {id: 20})-[:Transfers]->{1,3}(dst:Account)
RETURN DISTINCT dst.id AS dst;
결과
dst |
---|
7 |
16 |
20 |
그러나 계정 ID 20
로 반환되는 쿼리는 계정 ID 20
로 시작하기 때문에 지나치게 광범위한 쿼리일 수 있습니다. 더 구체적인 결과를 표시하려면 반복되는 노드가 없는 비순환 그래프 경로만 표시하도록 쿼리를 적용할 수 있습니다.
이렇게 하려면 다음 단계를 따르세요.
MATCH p = ACYCLIC <path_pattern>
를 사용합니다.- 쿼리에
IS_ACYCLIC(p)
필터 적용
다음 쿼리는 MATCH p = ACYCLIC PATH_PATTERN
를 사용합니다.
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->{1,3}(dst:Account)
RETURN DISTINCT dst.id AS dst;
결과
dst |
---|
7 |
16 |
금액이 송금되는 첫 번째 계정을 알고 싶다면 다음 쿼리를 실행하면 됩니다.
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})(-[:Transfers]->
(nexts:Account)){1,3}(dst:Account)
RETURN dst.id AS dst, ARRAY_AGG(DISTINCT nexts[0].id) AS unique_starts;
이 쿼리는 nexts
를 사용하여 결과를 가져오는 정량화된 경로 내에 새 변수를 도입하므로 일반적이지 않습니다. 경로 변수를 사용하면 쿼리를 간소화할 수 있습니다.
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->{1,3}(dst:Account)
RETURN dst.id AS dst, ARRAY_AGG(DISTINCT NODES(p)[OFFSET(1)].id) AS unique_starts;
NODES(p)
를 사용하면 경로의 모든 노드가 반환됩니다. 첫 번째 노드 계정이 start
로 지정되므로 다음 계정 (첫 번째 오프셋)은 송금이 이루어지는 첫 번째 계정입니다.
결과
dst | unique_starts |
---|---|
7 | 16, 7 |
경로는 정량화된 경로가 여러 개인 경우에 더 유용합니다. start
에서 찾은 경로가 계정 ID 7
를 통과해야 한다는 제약 조건을 추가할 수 있습니다.
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->
{1,3}(mid:Account {id: 7})-[:Transfers]->{1,3}(dst:Account)
RETURN dst.id AS dst,
ARRAY_AGG(DISTINCT NODES(p)[OFFSET(1)].id) AS unique_starts;
MATCH
문이 변경되었지만 나머지 쿼리는 변경할 필요가 없습니다. 경로 변수를 사용하지 않으면 Spanner가 검사할 정량화된 경로를 정적으로 알 수 없는 경우가 있습니다.
경로 변수를 사용하면 모든 송금의 합계를 가져올 수 있습니다.
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->
{1,3}(mid:Account {id: 7})-[:Transfers]->{1,3}(dst:Account)
LET all_transfers = EDGES(p)
LET transfer_amounts = SUM(all_transfers.amount)
RETURN dst.id AS dst,
ARRAY_AGG(DISTINCT NODES(p)[OFFSET(1)].id) AS participating_neighbor_nodes, transfer_amounts;
결과
dst | participating_neighbor_nodes | transfer_amounts |
---|---|---|
16 | 7 | 600 |
16 | 7 | 800 |