Auf dieser Seite wird beschrieben, wie Sie mit Graphpfad in Spanner Graph arbeiten.
In Graphdatenbanken stellt der Datentyp „Graphpfad“ eine Sequenz von Knoten dar, die mit Kanten verschachtelt sind, und zeigt, wie diese Knoten und Kanten miteinander in Beziehung stehen. Weitere Informationen zum Pfaddatentyp finden Sie unter Grafikpfadtyp.
Mit der Spanner Graph Language (GQL) können Sie Graphpfade erstellen und Abfragen darauf ausführen. In den Beispielen in diesem Dokument wird dasselbe Spanner Graph-Schema verwendet wie auf der Seite Cloud Spanner Graph einrichten und abfragen.
Graphpfad erstellen
Sie können einen Graphpfad erstellen, indem Sie eine Pfadvariable in einem Graphmuster oder mit der Funktion PATH
erstellen.
Wir empfehlen, einen Graphpfad mithilfe der Pfadvariablen zu erstellen. Das Format zum Erstellen einer Pfadvariablen lautet:
MATCH p = PATH_PATTERN
Weitere Informationen finden Sie unter Graphmuster.
Beispiel
Im folgenden Beispiel werden mit der Abfrage Muster von Überweisungen zwischen Konten innerhalb von FinGraph
ermittelt.
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;
Ergebnis
full_path |
---|
[{"identifier": ..., "properties": {"id": 16, ...}, ...}, {"identifier": ..., "properties": {"amount": 300.0, ...}, ...}, ...] |
Das Ergebnis gibt an, dass die Abfrage das Muster Account -> Transfers -> Account
in der Datenbank gefunden hat.
Graphpfad abfragen
Mit den folgenden pfadspezifischen Funktionen können Sie einen Graphpfad abfragen. Allgemeine Informationen zu Spanner Graph-Abfragen finden Sie unter Abfragen – Übersicht.
EDGES
Die Funktion EDGES
gibt alle Kanten in einem Graphenpfad zurück. Weitere Informationen zur Semantik finden Sie unter EDGES
.
Beispiel
Mit dieser Abfrage wird ein Pfad zwischen zwei Konten gefunden, der über ein Mittelkonto führt.
Er gibt den Wert der zweiten Transfers
-Kante im Pfad zurück, die sich zwischen src
und mid
oder zwischen mid
und dst
befinden kann.
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;
Ergebnis
src | dst | second_edge_amount |
---|---|---|
7 | 16 | 300 |
NODES
Die Funktion NODES
gibt alle Knoten in einem Graphenpfad zurück. Weitere Informationen zur Semantik finden Sie unter NODES
.
Beispiel
Mit dieser Abfrage wird der Graphpfad von zwei Übergängen ermittelt und dann eine JSON-Liste zurückgegeben, die den Pfad darstellt.
GRAPH FinGraph
MATCH p = (src:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(dst:Account)
RETURN TO_JSON(NODES(p)) AS nodes;
Ergebnis
Knoten |
---|
[{"identifier": "...", "properties": {"id": 16}, ...}, {"identifier": "...", "properties": {"id": 20, ...}, ...] |
… |
PATH_FIRST
Die Funktion PATH_FIRST
sucht den ersten Knoten in einem Graphenpfad. Weitere Informationen zur Semantik finden Sie unter PATH_FIRST
.
Beispiel
Mit dieser Abfrage wird der erste Knoten in einem Graphpfad mit zwei Übergängen ermittelt. Es gibt das Label des Knotens Account
und den Alias des Kontos zurück.
GRAPH FinGraph
MATCH p = -[:Transfers]->{1,3}(dst:Account{id: 7})
RETURN DISTINCT PATH_FIRST(p).id AS can_reach_target;
Ergebnis
can_reach_target |
---|
7 |
16 |
20 |
PATH_LAST
Die Funktion PATH_LAST
ermittelt den letzten Knoten in einem Graphpfad. Weitere Informationen zur Semantik finden Sie unter PATH_LAST
.
Beispiel
Mit dieser Abfrage wird der letzte Knoten in einem Graphpfad mit zwei Übertragungen gefunden. Es gibt das Label des Knotens Account
und den Alias des Kontos zurück.
GRAPH FinGraph
MATCH p =(start:Account{id: 7})-[:Transfers]->{1,3}
RETURN DISTINCT PATH_LAST(p).id as can_reach_target;
Ergebnis
can_reach_target |
---|
7 |
16 |
20 |
PATH_LENGTH
Mit der Funktion PATH_LENGTH
wird die Anzahl der Kanten in einem Graphenpfad ermittelt. Weitere Informationen zur Semantik finden Sie unter PATH_LENGTH
.
Beispiel
Mit dieser Abfrage wird die Anzahl der Kanten in einem Graphenpfad ermittelt, der ein bis drei Übergänge enthält.
GRAPH FinGraph
MATCH p = (src:Account)-[e:Transfers]->{1,3}(dst:Account)
RETURN PATH_LENGTH(p) AS num_transfers, COUNT(*) AS num_paths;
Ergebnis
num_transfers | num_paths |
---|---|
1 | 5 |
2 | 7 |
3 | 11 |
IS_ACYCLIC
Mit der Funktion IS_ACYCLIC
wird geprüft, ob ein Graphpfad sich wiederholende Knoten enthält. Wenn eine Wiederholung gefunden wird, wird TRUE
zurückgegeben, andernfalls FALSE
. Weitere Informationen zur Semantik finden Sie unter IS_ACYCLIC
.
Beispiel
Mit dieser Abfrage wird geprüft, ob dieser Graphpfad sich wiederholende Knoten enthält.
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;
Ergebnis
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
Mit der Funktion IS_TRAIL
wird geprüft, ob ein Graphpfad sich wiederholende Kanten enthält. Wenn eine Wiederholung gefunden wird, wird TRUE
zurückgegeben, andernfalls FALSE
. Weitere Informationen zur Semantik finden Sie unter IS_TRAIL
.
Beispiel
Mit dieser Abfrage wird geprüft, ob dieser Graphpfad sich wiederholende Kanten hat.
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;
Ergebnis
is_trail_path | t1_id | t2_id | t3_id |
---|---|---|---|
FALSE | 16 | 20 | 16 |
TRUE | 7 | 16 | 20 |
TRUE | 7 | 16 | 20 |
Pfadmodi
In Spanner Graph werden standardmäßig alle Pfade zurückgegeben, einschließlich Pfade mit sich wiederholenden Knoten und Kanten. Mit den folgenden Pfadmodi können Sie Pfade mit sich wiederholenden Knoten und Kanten ein- oder ausschließen. Weitere Informationen zur Semantik finden Sie in der Pathmode-Dokumentation.
WALK
Im Pfadmodus WALK
werden alle Pfade zurückgegeben, einschließlich Pfade mit sich wiederholenden Knoten und Kanten. WALK
ist der Standardpfadmodus.
Beispiel
In der folgenden Abfrage wird die Verwendung des Pfadmodus WALK
für ein nicht quantifiziertes Pfadmuster veranschaulicht. Der erste Pfad in den Ergebnissen verwendet dieselbe Kante für t1
und 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;
Ergebnis
transfer1_id | transfer2_id | transfer3_id |
---|---|---|
16 | 20 | 16 |
7 | 16 | 20 |
7 | 16 | 20 |
ACYCLIC
Im Pfadmodus ACYCLIC
werden Pfade mit sich wiederholenden Knoten herausgefiltert.
Beispiel
In der folgenden Abfrage wird die Verwendung des Pfadmodus ACYCLIC
für ein nicht quantifiziertes Pfadmuster veranschaulicht.
Der Pfad mit den gleichen src
- und dst
-Knoten wird herausgefiltert.
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;
Ergebnis
account1_id | account2_id | account3_id |
---|---|---|
20 | 7 | 16 |
20 | 7 | 16 |
7 | 16 | 20 |
7 | 16 | 20 |
16 | 20 | 7 |
TRAIL
Im Pfadmodus TRAIL
werden Pfade mit sich wiederholenden Kanten herausgefiltert.
Beispiel
In der folgenden Abfrage wird die Verwendung des Pfadmodus TRAIL
für ein nicht quantifiziertes Pfadmuster veranschaulicht. Der Pfad, dessen t1
- und t3
-Kanten gleich sind, wird herausgefiltert.
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;
Ergebnis
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 |
Pfadsuchpräfix
Mit einem Pfadsuchpräfix können Sie ein Pfadmuster so einschränken, dass der kürzeste Pfad aus jeder Datenpartition zurückgegeben wird. Ausführliche Informationen zur Semantik finden Sie unter Präfix für die Pfadsuche.
ANY SHORTEST
Das Pfadsuchpräfix ANY SHORTEST
gibt den kürzesten Pfad (den Pfad mit der geringsten Anzahl von Kanten) zurück, der mit dem Muster aus jeder Datenpartition übereinstimmt. Wenn es mehr als einen kürzesten Pfad pro Partition gibt, wird einer davon zurückgegeben.
Beispiel
Die folgende Abfrage entspricht jedem Pfad zwischen jedem Paar von [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;
Ergebnis
account1_id | total_amount | account2_id |
---|---|---|
16 | 500 | 16 |
16 | 800 | 7 |
16 | 300 | 20 |
Konversionsregeln
Weitere Informationen finden Sie unter Konvertierungsregeln für GRAPH_PATH.
Beispiel für einen Anwendungsfall
Im folgenden Anwendungsfallbeispiel sehen Sie, dass alle Konten über ein bis drei Konten von der Konto-ID 20
aus weitergeleitet wurden.
GRAPH FinGraph
MATCH p = (start:Account {id: 20})-[:Transfers]->{1,3}(dst:Account)
RETURN DISTINCT dst.id AS dst;
Ergebnis
dst |
---|
7 |
16 |
20 |
Eine Abfrage, die zur Konto-ID 20
zurückgibt, ist jedoch möglicherweise zu breit, da sie mit der Konto-ID 20
beginnt. Wenn Sie spezifischere Ergebnisse erhalten möchten, können Sie in Ihrer Abfrage festlegen, dass nur azyklische Graphpfade ohne sich wiederholende Knoten angezeigt werden.
Dazu haben Sie folgende Möglichkeiten:
- Verwenden Sie
MATCH p = ACYCLIC <path_pattern>
. IS_ACYCLIC(p)
-Filter in die Abfrage einfügen
In der folgenden Abfrage wird MATCH p = ACYCLIC PATH_PATTERN
verwendet:
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->{1,3}(dst:Account)
RETURN DISTINCT dst.id AS dst;
Ergebnis
dst |
---|
7 |
16 |
Wenn Sie wissen möchten, über welches Konto das Geld zuerst überwiesen wird, können Sie die folgende Abfrage ausführen:
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;
Diese Abfrage ist unkonventionell, da sie eine neue Variable im quantifizierten Pfad einführt, um mit nexts
das Ergebnis zu erhalten. Mit Pfadvariablen können Sie die Abfrage vereinfachen:
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;
Mit NODES(p)
werden alle Knoten entlang des Pfades zurückgegeben. Da das erste Knottenkonto als start
angegeben ist, ist das nächste Konto (beim ersten Offset) das erste Konto, über das Geld überwiesen wird.
Ergebnis
dst | unique_starts |
---|---|
7 | 16, 7 |
Pfade sind besonders nützlich, wenn es mehrere quantifizierte Pfade gibt. Sie können eine Einschränkung hinzufügen, dass die von start
gefundenen Pfade die Konto-ID 7
durchlaufen müssen:
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;
Auch wenn sich die MATCH
-Anweisung geändert hat, muss der Rest der Abfrage nicht geändert werden. Ohne Pfadvariablen kann Spanner in einigen Fällen nicht statisch erkennen, welcher quantifizierte Pfad geprüft werden soll.
Mit einer Pfadvariablen können Sie die Summe aller Übertragungen ermitteln:
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;
Ergebnis
dst | participating_neighbor_nodes | transfer_amounts |
---|---|---|
16 | 7 | 600 |
16 | 7 | 800 |