本頁面說明如何在 Spanner 圖表中使用圖表路徑。
在圖形資料庫中,圖形路徑資料類型代表節點與邊緣交錯的序列,並顯示這些節點和邊緣的關聯方式。如要進一步瞭解路徑資料類型,請參閱「圖形路徑類型」。
您可以使用 Spanner Graph Language (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;
結果
節點 |
---|
[{"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
。
範例
這項查詢會找出圖表路徑中包含一到三次轉移的邊數量。
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 中,預設行為是傳回所有路徑,包括含有重複節點和邊的路徑。您可以使用下列路徑模式,加入或排除含有重複節點和邊緣的路徑。如需詳細語意說明,請參閱 Path 模式說明文件。
WALK
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 {is_blocked:true})-[t:Transfers]->{1,4}(b:Account)
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
中的一到三個帳戶進行路由。
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 |