Auf dieser Seite wird beschrieben, wie Sie mit Pfaden in Spanner Graph arbeiten.
In Graphendatenbanken stellt der Datentyp „Graphpfad“ eine Folge von Knoten dar, die mit Kanten verschachtelt sind, und zeigt, wie diese Knoten und Kanten zusammenhängen. Weitere Informationen zum Datentyp „Pfad“ finden Sie unter Datentyp „Graphpfad“.
Mit der Spanner Graph Language (GQL) können Sie Diagrammpfade erstellen und Abfragen für diese Pfade ausführen. In den Beispielen in diesem Dokument wird dasselbe Spanner Graph-Schema verwendet wie auf der Seite Cloud Spanner Graph einrichten und abfragen.
Diagrammpfad erstellen
Sie können einen Pfad im Diagramm erstellen, indem Sie eine Pfadvariable in einem Diagrammmuster oder mit der PATH
-Funktion erstellen.
Wir empfehlen, einen Diagrammpfad mit der Pfadvariablen zu erstellen. Das Format zum Erstellen einer Pfadvariablen ist:
MATCH p = PATH_PATTERN
Weitere Informationen finden Sie unter Graph-Muster.
Beispiel
Im folgenden Beispiel werden mit der Abfrage Muster für Geldüberweisungen zwischen Konten in FinGraph
gesucht.
GRAPH FinGraph
MATCH p = (src:Account {id: 16})-[t:Transfers]->{2}(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 zeigt, dass das Muster Account -> Transfers -> Account
in der Datenbank gefunden wurde.
Graphpfad abfragen
Mit den folgenden pfadspezifischen Funktionen können Sie einen Diagrammpfad abfragen. Allgemeine Informationen zu Spanner Graph-Abfragen finden Sie unter Übersicht über Abfragen.
EDGES
Die Funktion EDGES
gibt alle Kanten in einem Graphpfad zurück. Eine detaillierte Beschreibung der Semantik finden Sie unter EDGES
.
Beispiel
Mit dieser Abfrage wird ein Pfad zwischen zwei Konten gefunden, der über ein mittleres Konto verläuft.
Es wird der Betrag der zweiten Transfers
-Kante im Pfad zurückgegeben, der zwischen src
und mid
oder zwischen mid
und dst
liegen 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 Diagrammpfad zurück. Eine detaillierte Beschreibung der Semantik finden Sie unter NODES
.
Beispiel
Mit dieser Abfrage wird der Pfad im Diagramm von zwei Transfers ermittelt und dann eine JSON-Liste zurückgegeben, die den Pfad darstellt.
GRAPH FinGraph
MATCH p = (src:Account)-[t:Transfers]->{2}(dst:Account)
RETURN TO_JSON(NODES(p)) AS nodes;
Ergebnis
Knoten |
---|
[{"identifier": "...", "properties": {"id": 16}, ...}, {"identifier": "...", "properties": {"id": 20, ...}, ...] |
… |
PATH_FIRST
Mit der Funktion PATH_FIRST
wird der erste Knoten in einem Diagrammpfad gesucht. Eine detaillierte Beschreibung der Semantik finden Sie unter PATH_FIRST
.
Beispiel
Mit dieser Abfrage wird der erste Knoten in einem Diagrammpfad mit zwei Transfers ermittelt. Es gibt das Label des Account
-Knotens 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
Mit der Funktion PATH_LAST
wird der letzte Knoten in einem Graphpfad ermittelt. Eine detaillierte Beschreibung der Semantik finden Sie unter PATH_LAST
.
Beispiel
Mit dieser Abfrage wird der letzte Knoten in einem Diagrammpfad mit zwei Transfers ermittelt. Es gibt das Label des Account
-Knotens 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 Diagrammpfad ermittelt. Ausführliche Informationen zur Semantik finden Sie unter PATH_LENGTH
.
Beispiel
Mit dieser Abfrage wird die Anzahl der Kanten in einem Diagrammpfad ermittelt, der ein bis drei Transfers 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
Die Funktion IS_ACYCLIC
prüft, ob ein Diagrammpfad sich wiederholende Knoten enthält. Die Funktion gibt TRUE
zurück, wenn eine Wiederholung gefunden wird, andernfalls FALSE
. Eine detaillierte Beschreibung der Semantik finden Sie unter IS_ACYCLIC
.
Beispiel
Mit dieser Abfrage wird geprüft, ob dieser Diagrammpfad sich wiederholende Knoten enthält.
GRAPH FinGraph
MATCH p = (src:Account)-[t:Transfers]->{2}(dst:Account)
RETURN IS_ACYCLIC(p) AS is_acyclic_path,
ARRAY_TRANSFORM(NODES(p), n->n.id) AS account_ids;
Ergebnis
is_acyclic_path | account_ids |
---|---|
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
Die Funktion IS_TRAIL
prüft, ob ein Graphpfad sich wiederholende Kanten enthält. Die Funktion gibt TRUE
zurück, wenn eine Wiederholung gefunden wird, andernfalls FALSE
. Eine detaillierte Beschreibung der Semantik finden Sie unter IS_TRAIL
.
Beispiel
Mit dieser Abfrage wird geprüft, ob dieser Diagrammpfad sich wiederholende Kanten enthält.
GRAPH FinGraph
MATCH p = (src:Account)-[t:Transfers]->{3}(dst:Account)
WHERE src.id < dst.id
RETURN IS_TRAIL(p) AS is_trail_path,
ARRAY_TRANSFORM(t, t->t.id) AS transfer_ids
Ergebnis
is_trail_path | transfer_ids |
---|---|
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 Pfaden mit sich wiederholenden Knoten und Kanten. Sie können die folgenden Pfadmodi verwenden, um Pfade mit sich wiederholenden Knoten und Kanten ein- oder auszuschließen. Eine detaillierte Beschreibung der Semantik finden Sie in der Dokumentation zum Pfadmodus.
WALK
Im Pfadmodus WALK
werden alle Pfade zurückgegeben, einschließlich Pfade mit sich wiederholenden Knoten und Kanten. WALK
ist der Standardpfadmodus.
Beispiel
Die folgende Abfrage veranschaulicht die Verwendung des Pfadmodus WALK
für ein quantifiziertes Pfadmuster.
Der erste Pfad in den Ergebnissen hat wiederholte Kanten.
GRAPH FinGraph
MATCH p = WALK (src:Account)-[t:Transfers]->{3}(dst:Account)
WHERE src.id < dst.id
RETURN ARRAY_TRANSFORM(t, t->t.id) AS transfer_ids
Ergebnis
transfer_ids |
---|
16,20,16 |
7,16,20 |
7,16,20 |
ACYCLIC
Im Pfadmodus ACYCLIC
werden Pfade mit sich wiederholenden Knoten herausgefiltert.
Beispiel
Die folgende Abfrage veranschaulicht die Verwendung des Pfadmodus ACYCLIC
für ein quantifiziertes Pfadmuster.
Der Pfad mit gleichen src
- und dst
-Knoten wird herausgefiltert.
GRAPH FinGraph
MATCH p = ACYCLIC (src:Account)-[t:Transfers]->{2}(dst:Account)
RETURN ARRAY_TRANSFORM(NODES(p), n->n.id) AS account_ids
Ergebnis
account_ids |
---|
16,20,7 |
20,7,16 |
20,7,16 |
7,16,20 |
7,16,20 |
TRAIL
Im Pfadmodus TRAIL
werden Pfade mit sich wiederholenden Kanten herausgefiltert.
Beispiel
Die folgende Abfrage veranschaulicht die Verwendung des Pfadmodus TRAIL
für ein quantifiziertes Pfadmuster.
Pfade mit wiederholten Kanten werden herausgefiltert.
GRAPH FinGraph
MATCH p = TRAIL (src:Account)-[t:Transfers]->{3}(dst:Account)
WHERE src.id < dst.id
RETURN ARRAY_TRANSFORM(t, t->t.id) AS transfer_ids
Ergebnis
transfer_ids |
---|
7,16,20 |
7,16,20 |
Pfadsuchpräfix
Sie können ein Pfadsuchpräfix verwenden, um ein Pfadmuster so einzuschränken, dass der kürzeste Pfad aus jeder Datenpartition zurückgegeben wird. Eine detaillierte Beschreibung der Semantik finden Sie unter Präfix für die Pfadsuche.
ANY SHORTEST
Das Suchpräfix für den Pfad ANY SHORTEST
gibt den kürzesten Pfad (den Pfad mit der geringsten Anzahl von Kanten) zurück, der dem Muster aus jeder Datenpartition entspricht. Wenn es mehrere kürzeste Pfade pro Partition gibt, wird einer davon zurückgegeben.
Beispiel
Die folgende Abfrage entspricht jedem Pfad zwischen den einzelnen [a, b]
-Paaren.
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;
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 Beispiel für einen Anwendungsfall sehen Sie, dass alle Konten über ein bis drei Konten weitergeleitet wurden, beginnend mit der Konto-ID 20
.
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 die Konto-ID 20
zurückgibt, ist möglicherweise zu breit gefasst, da sie mit der Konto-ID 20
beginnt. Um spezifischere Ergebnisse zu erhalten, können Sie erzwingen, dass in Ihrer Abfrage nur azyklische Graphpfade ohne sich wiederholende Knoten angezeigt werden.
Dazu haben Sie folgende Möglichkeiten:
- Verwenden Sie
MATCH p = ACYCLIC <path_pattern>
oder - Wenden Sie in Ihrer Anfrage einen
IS_ACYCLIC(p)
-Filter an.
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 mit nexts
einführt, um 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;
Wenn Sie NODES(p)
verwenden, werden alle Knoten auf dem Pfad zurückgegeben. Da das erste Knotenpunktkonto 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 nützlicher, wenn es mehrere quantifizierte Pfade gibt. Sie können eine Einschränkung hinzufügen, dass die Pfade, die über start
gefunden werden, 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;
Obwohl 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 ermitteln, welcher quantifizierte Pfad untersucht werden soll.
Mit einer Pfadvariablen können Sie die Summe aller Übertragungen abrufen:
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 |