In diesem Dokument erhalten Sie einen Überblick über die Verwendung der Graph Query Language mit Spanner Graph, einschließlich der Syntax für den Abgleich von Graphmustern. Außerdem wird gezeigt, wie Sie Abfragen für Ihren Graphen ausführen. Mit Spanner Graph können Sie Abfragen ausführen, um Muster zu finden, Beziehungen zu durchlaufen und Erkenntnisse aus Ihren Property Graph-Daten zu gewinnen.
In den Beispielen in diesem Dokument wird das Graphschema verwendet, das Sie unter Cloud Spanner Graph einrichten und abfragen erstellen. Dieses Schema wird im folgenden Diagramm veranschaulicht:
Spanner Graph-Abfrage ausführen
Sie können eine Spanner Graph-Abfrage mit der Google Cloud Console, der Google Cloud CLI, Clientbibliotheken, der REST API oder der RPC API ausführen.
Google Cloud Console
In den folgenden Schritten wird beschrieben, wie Sie eine Abfrage in derGoogle Cloud -Konsole ausführen. Bei diesen Schritten wird davon ausgegangen, dass Sie eine Instanz namens test-instance haben, die eine Datenbank namens example-db enthält. Informationen zum Erstellen einer Instanz mit einer Datenbank finden Sie unter Spanner Graph einrichten und abfragen.
Rufen Sie in der Google Cloud Console die Seite Spanner-Instanzen auf.
Klicken Sie auf die Instanz mit dem Namen
test-instance.Klicken Sie unter Datenbanken auf die Datenbank mit dem Namen
example-db.Öffnen Sie Spanner Studio und klicken Sie dann auf Neuer Tab oder verwenden Sie den Editor-Tab.
Geben Sie eine Abfrage in den Abfrageeditor ein.
Klicken Sie auf Ausführen.
gcloud-CLI
So senden Sie Abfragen mit dem gcloud CLI-Befehlszeilentool:
Installieren Sie die gcloud CLI, falls sie noch nicht installiert ist.
Führen Sie in der gcloud CLI den folgenden Befehl aus:
Weitere Informationen finden Sie in der Spanner-CLI-Kurzanleitung.
REST API
Verwenden Sie einen der folgenden Befehle, um Anfragen über die REST API zu senden:
Weitere Informationen finden Sie unter Daten mit der REST API abfragen und Erste Schritte mit Spanner über REST.
RPC API
Verwenden Sie einen der folgenden Befehle, um Abfragen über die RPC API zu senden:
Clientbibliotheken
Weitere Informationen zum Ausführen einer Abfrage mit einer Spanner-Clientbibliothek finden Sie unter:
- Abfrage mit der Spanner-C++-Clientbibliothek
- Abfragen mit der Spanner-C#-Clientbibliothek
- Abfrage mit der Spanner Go-Clientbibliothek
- Abfragen mit der Spanner-Java-Clientbibliothek
- Abfragen mit der Spanner Node.js-Clientbibliothek
- Abfragen mit der Spanner-PHP-Clientbibliothek
- Abfrage mit der Spanner-Python-Clientbibliothek
- Abfrage mit der Spanner-Clientbibliothek für Ruby
Weitere Informationen zu den Spanner-Clientbibliotheken finden Sie in der Übersicht zu Spanner-Clientbibliotheken.
Ergebnisse von Spanner Graph-Abfragen visualisieren
Sie können sich eine visuelle Darstellung Ihrer Spanner Graph-Abfrageergebnisse in Spanner Studio in der Google Cloud Konsole ansehen. Mit einer Abfragevisualisierung können Sie sehen, wie die zurückgegebenen Elemente (Knoten und Kanten) miteinander verbunden sind. So lassen sich Muster, Abhängigkeiten und Anomalien erkennen, die in einer Tabelle nur schwer zu sehen sind. Damit eine Visualisierung einer Abfrage angezeigt werden kann, müssen mit der Abfrage vollständige Knoten im JSON-Format zurückgegeben werden. Andernfalls können Sie die Abfrageergebnisse nur in Tabellenform sehen. Weitere Informationen finden Sie unter Visualisierungen von Spanner Graph-Abfragen verwenden.
Abfragestruktur für Spanner Graph
Eine Spanner Graph-Abfrage besteht aus mehreren Komponenten, z. B. dem Namen des Eigenschaftsgraphen, Knoten- und Kantenmustern sowie Quantoren. Mit diesen Komponenten erstellen Sie eine Abfrage, mit der Sie bestimmte Muster in Ihrem Diagramm finden. Jede Komponente wird im Abschnitt Musterabgleich für Graphen dieses Dokuments beschrieben.
Die Abfrage in Abbildung 2 zeigt die grundlegende Struktur einer Spanner Graph-Abfrage. Die Abfrage beginnt mit der Angabe des Zielgraphen FinGraph mit der GRAPH-Anweisung. Die MATCH-Klausel definiert dann das Muster, nach dem gesucht werden soll. In diesem Fall ist es ein Person-Knoten, der über eine Owns-Kante mit einem Account-Knoten verbunden ist. Die RETURN-Klausel gibt an, welche Eigenschaften der übereinstimmenden Knoten zurückgegeben werden sollen.
Musterabgleich für Grafiken
Beim Musterabgleich für Grafiken werden bestimmte Muster in Ihrem Diagramm gesucht. Die einfachsten Muster sind Elementmuster, z. B. Knotenmuster, die mit Knoten übereinstimmen, und Kantenmuster, die mit Kanten übereinstimmen.
Knotenmuster
Ein Knotenmuster entspricht Knoten in Ihrem Diagramm. Dieses Muster enthält übereinstimmende Klammern, die optional eine Graphmuster-Variable, einen Label-Ausdruck und Property-Filter enthalten können.
Alle Knoten finden
Die folgende Abfrage gibt alle Knoten im Diagramm zurück. Die Variable n, eine Variable für das Diagrammmuster, wird an die übereinstimmenden Knoten gebunden. In diesem Fall entspricht das Knotenmuster allen Knoten im Diagramm.
GRAPH FinGraph
MATCH (n)
RETURN LABELS(n) AS label, n.id;
Diese Abfrage gibt label und id zurück:
| Label | id |
|---|---|
| Konto | 7 |
| Konto | 16 |
| Konto | 20 |
| Person | 1 |
| Person | 2 |
| Person | 3 |
Alle Knoten mit einem bestimmten Label finden
Die folgende Abfrage stimmt mit allen Knoten im Diagramm überein, die das Person-Label haben.
Die Abfrage gibt die Eigenschaften label, id und name der übereinstimmenden Knoten zurück.
GRAPH FinGraph
MATCH (p:Person)
RETURN LABELS(p) AS label, p.id, p.name;
Diese Abfrage gibt die folgenden Eigenschaften der übereinstimmenden Knoten zurück:
| Label | id | Name |
|---|---|---|
| Person | 1 | Alex |
| Person | 2 | Dana |
| Person | 3 | Lee |
Alle Knoten finden, die einem Label-Ausdruck entsprechen
Sie können einen Label-Ausdruck mit einem oder mehreren logischen Operatoren erstellen. Die folgende Abfrage entspricht beispielsweise allen Knoten im Diagramm, die entweder das Label Person oder Account haben. Die Graphmustervariable n macht alle Attribute von Knoten mit dem Label Person oder Account verfügbar.
GRAPH FinGraph
MATCH (n:Person|Account)
RETURN LABELS(n) AS label, n.id, n.birthday, n.create_time;
In den folgenden Ergebnissen dieser Abfrage:
- Alle Knoten haben das Attribut
id. - Knoten, die dem Label
Accountentsprechen, haben die Propertycreate_time, aber nicht die Propertybirthday. Das Attributbirthdayist für diese KnotenNULL. - Knoten, die dem Label
Personentsprechen, haben das Attributbirthday, aber nicht das Attributcreate_time. Das Attributcreate_timeist für diese KnotenNULL.
| Label | id | Geburtstag | create_time |
|---|---|---|---|
| Konto | 7 | NULL | 2020-01-10T14:22:20.222Z |
| Konto | 16 | NULL | 2020-01-28T01:55:09.206Z |
| Konto | 20 | NULL | 2020-02-18T13:44:20.655Z |
| Person | 1 | 1991-12-21T08:00:00Z | NULL |
| Person | 2 | 1980-10-31T08:00:00Z | NULL |
| Person | 3 | 1986-12-07T08:00:00Z | NULL |
Alle Knoten finden, die dem Label-Ausdruck und dem Eigenschaftsfilter entsprechen
Diese Abfrage entspricht allen Knoten im Diagramm, die das Label Person haben und bei denen die Property id gleich 1 ist.
GRAPH FinGraph
MATCH (p:Person {id: 1})
RETURN LABELS(p) AS label, p.id, p.name, p.birthday;
Hier sind die Abfrageergebnisse:
| Label | id | Name | Geburtstag |
|---|---|---|---|
| Person | 1 | Alex | 1991-12-21T08:00:00Z |
Mit der WHERE-Klausel können Sie komplexere Filterbedingungen für Labels und Attribute erstellen.
In der folgenden Abfrage wird die WHERE-Anweisung verwendet, um eine komplexere Filterbedingung für Properties zu erstellen. Sie entspricht allen Knoten im Diagramm, die das Label Person haben und deren Attribut birthday vor 1990-01-10 liegt.
GRAPH FinGraph
MATCH (p:Person WHERE p.birthday < '1990-01-10')
RETURN LABELS(p) AS label, p.name, p.birthday;
Hier sind die Abfrageergebnisse:
| Label | Name | Geburtstag |
|---|---|---|
| Person | Dana | 1980-10-31T08:00:00Z |
| Person | Lee | 1986-12-07T08:00:00Z |
Edge-Muster
Ein Kantenmuster entspricht Kanten oder Beziehungen zwischen Knoten. Kantenmuster werden in eckige Klammern ([]) gesetzt und enthalten Symbole wie -, -> oder <-, um Richtungen anzugeben. Ein Kantenmuster kann optional eine Graphmustervariable enthalten, die an übereinstimmende Kanten gebunden wird.
Alle Kanten mit übereinstimmenden Labels finden
Diese Abfrage gibt alle Kanten im Diagramm mit dem Label Transfers zurück. Mit der Abfrage wird die Variable e des Diagrammmusters an die übereinstimmenden Kanten gebunden.
GRAPH FinGraph
MATCH -[e:Transfers]->
RETURN e.Id as src_account, e.order_number
Hier sind die Abfrageergebnisse:
| src_account | order_number |
|---|---|
| 7 | 304330008004315 |
| 7 | 304120005529714 |
| 16 | 103650009791820 |
| 20 | 304120005529714 |
| 20 | 302290001255747 |
Alle Kanten finden, die dem Label-Ausdruck und dem Attributfilter entsprechen
Das Kantenmuster dieser Abfrage verwendet einen Label-Ausdruck und einen Attributfilter, um alle Kanten mit dem Label Transfers zu finden, die einem angegebenen order_number entsprechen.
GRAPH FinGraph
MATCH -[e:Transfers {order_number: "304120005529714"}]->
RETURN e.Id AS src_account, e.order_number
Hier sind die Abfrageergebnisse:
| src_account | order_number |
|---|---|
| 7 | 304120005529714 |
| 20 | 304120005529714 |
Alle Kanten mit einem beliebigen Richtungskantenmuster finden
Sie können das any direction-Kantenmuster (-[]-) in einer Abfrage verwenden, um Kanten in beide Richtungen abzugleichen. Mit der folgenden Abfrage werden alle Überweisungen mit einem gesperrten Konto gefunden.
GRAPH FinGraph
MATCH (account:Account)-[transfer:Transfers]-(:Account {is_blocked:true})
RETURN transfer.order_number, transfer.amount;
Hier sind die Abfrageergebnisse:
| order_number | amount |
|---|---|
| 304330008004315 | 300 |
| 304120005529714 | 100 |
| 103650009791820 | 300 |
| 302290001255747 | 200 |
Pfadmuster
Ein Pfadmuster besteht aus abwechselnden Knoten- und Kantenmustern.
Alle Pfade von einem bestimmten Knoten mithilfe eines Pfadmusters finden
Mit der folgenden Abfrage werden alle Überweisungen an ein Konto gefunden, die von einem Konto mit id gleich 2 initiiert wurden, das Person gehört.
Jedes übereinstimmende Ergebnis stellt einen Pfad von Person {id: 2} über einen verbundenen Account mit der Owns-Kante in einen anderen Account mit der Transfers-Kante dar.
GRAPH FinGraph
MATCH
(p:Person {id: 2})-[:Owns]->(account:Account)-[t:Transfers]->
(to_account:Account)
RETURN
p.id AS sender_id, account.id AS from_id, to_account.id AS to_id;
Hier sind die Abfrageergebnisse:
| sender_id | from_id | to_id |
|---|---|---|
| 2 | 20 | 7 |
| 2 | 20 | 16 |
Quantifizierte Pfadmuster
Bei einem quantifizierten Muster wird ein Muster innerhalb eines bestimmten Bereichs wiederholt.
Ein quantifiziertes Kantenmuster abgleichen
Wenn Sie Pfade mit variabler Länge finden möchten, können Sie einen Quantor auf ein Kantenmuster anwenden. In der folgenden Abfrage wird dies veranschaulicht. Es werden Zielkonten gesucht, die ein bis drei Übertragungen von einem Quellkonto Account mit einem id von 7 entfernt sind.
In der Abfrage wird der Quantifizierer {1, 3} auf das Kantenmuster -[e:Transfers]-> angewendet. Dadurch wird die Abfrage angewiesen, Pfade abzugleichen, in denen das Transfers-Kantenmuster ein-, zwei- oder dreimal wiederholt wird. Mit der WHERE-Klausel wird das Quellkonto aus den Ergebnissen ausgeschlossen. Die Funktion ARRAY_LENGTH wird verwendet, um auf die group variable e zuzugreifen. Weitere Informationen finden Sie unter Variable für Zugriffsgruppe.
GRAPH FinGraph
MATCH (src:Account {id: 7})-[e:Transfers]->{1, 3}(dst:Account)
WHERE src != dst
RETURN src.id AS src_account_id, ARRAY_LENGTH(e) AS path_length, dst.id AS dst_account_id;
Hier sind die Abfrageergebnisse:
| src_account_id | path_length | dst_account_id |
|---|---|---|
| 7 | 1 | 16 |
| 7 | 1 | 16 |
| 7 | 1 | 16 |
| 7 | 3 | 16 |
| 7 | 3 | 16 |
| 7 | 2 | 20 |
| 7 | 2 | 20 |
Einige Zeilen in den Ergebnissen werden wiederholt. Das liegt daran, dass zwischen denselben Quell- und Zielknoten mehrere Pfade vorhanden sein können, die dem Muster entsprechen, und die Abfrage alle zurückgibt.
Quantifiziertes Pfadmuster abgleichen
Mit der folgenden Abfrage werden Pfade zwischen Account-Knoten mit ein bis zwei Transfers-Kanten über blockierte Zwischenkonten gefunden.
Das in Klammern gesetzte Pfadmuster wird quantifiziert und seine WHERE-Klausel gibt Bedingungen für das wiederholte Muster an.
GRAPH FinGraph
MATCH
(src:Account)
((a:Account)-[:Transfers]->(b:Account {is_blocked:true}) WHERE a != b){1,2}
-[:Transfers]->(dst:Account)
RETURN src.id AS src_account_id, dst.id AS dst_account_id;
Hier sind die Abfrageergebnisse:
| src_account_id | dst_account_id |
|---|---|
| 7 | 20 |
| 7 | 20 |
| 20 | 20 |
Gruppenvariablen
Eine in einem quantifizierten Muster deklarierte Graphmustervariable wird zu einer Gruppenvariablen, wenn außerhalb dieses Musters darauf zugegriffen wird. Anschließend wird eine Bindung an ein Array mit übereinstimmenden Grafikelementen hergestellt.
Sie können auf eine Gruppierungsvariable als Array zugreifen. Die Grafikelemente werden in der Reihenfolge ihrer Darstellung entlang der abgeglichenen Pfade beibehalten. Sie können eine Gruppierungsvariable mit horizontaler Aggregation aggregieren.
Variable für Zugriffsgruppe
Im folgenden Beispiel wird auf die Variable e so zugegriffen:
- Eine Graphmustervariable, die an eine einzelne Kante in der
WHERE-Klausel gebunden ist,e.amount > 100wenn sie sich im quantifizierten Muster befindet. - Eine Gruppierungsvariable, die an ein Array von Edge-Elementen in
ARRAY_LENGTH(e)in derRETURN-Anweisung gebunden ist, wenn sie sich außerhalb des quantifizierten Musters befindet. - Eine Gruppierungsvariable, die an ein Array von Edge-Elementen gebunden ist und von
SUM(e.amount)außerhalb des quantifizierten Musters aggregiert wird. Dies ist ein Beispiel für die horizontale Aggregation.
GRAPH FinGraph
MATCH
(src:Account {id: 7})-[e:Transfers WHERE e.amount > 100]->{0,2}
(dst:Account)
WHERE src.id != dst.id
LET total_amount = SUM(e.amount)
RETURN
src.id AS src_account_id, ARRAY_LENGTH(e) AS path_length,
total_amount, dst.id AS dst_account_id;
Hier sind die Abfrageergebnisse:
| src_account_id | path_length | total_amount | dst_account_id |
|---|---|---|---|
| 7 | 1 | 300 | 16 |
| 7 | 2 | 600 | 20 |
Präfixe für die Pfadsuche
Wenn Sie die abgeglichenen Pfade in Gruppen mit gemeinsamen Quell- und Zielknoten einschränken möchten, können Sie das Suchpräfix ANY oder ANY SHORTEST verwenden.
Sie können diese Präfixe nur vor einem gesamten Pfadmuster anwenden und nicht innerhalb von Klammern.
Abgleich mit ANY
Mit der folgenden Abfrage werden alle erreichbaren eindeutigen Konten gefunden, die ein oder zwei Transfers von einem bestimmten Account-Knoten entfernt sind.
Das Präfix ANY für die Pfadsuche sorgt dafür, dass die Abfrage nur einen Pfad zwischen einem eindeutigen Paar von src- und dst-Account-Knoten zurückgibt. Im folgenden Beispiel können Sie den Knoten Account zwar über zwei verschiedene Pfade vom Quellknoten Account aus mit {id: 16} erreichen, die Abfrage gibt aber nur einen Pfad zurück.
GRAPH FinGraph
MATCH ANY (src:Account {id: 7})-[e:Transfers]->{1,2}(dst:Account)
LET ids_in_path = ARRAY_CONCAT(ARRAY_AGG(e.Id), [dst.Id])
RETURN src.id AS src_account_id, dst.id AS dst_account_id, ids_in_path;
Hier sind die Abfrageergebnisse:
| src_account_id | dst_account_id | ids_in_path |
|---|---|---|
| 7 | 16 | 7,16 |
| 7 | 20 | 7,16,20 |
Diagrammmuster
Ein Diagrammmuster besteht aus einem oder mehreren Pfadmuster, die durch ein Komma (,) getrennt sind. Diagrammmuster können eine WHERE-Klausel enthalten, mit der Sie auf alle Variablen des Diagrammmusters in den Pfadmuster zugreifen können, um Filterbedingungen zu erstellen. Jedes Pfadmuster erzeugt eine Sammlung von Pfaden.
Mit einem Graphmuster abgleichen
Mit der folgenden Abfrage werden Vermittlerkonten und ihre Inhaber ermittelt, die an Transaktionsbeträgen über 200 € beteiligt sind, über die Geld von einem Quellkonto auf ein gesperrtes Konto überwiesen wird.
Die folgenden Pfadmuster bilden das Diagrammmuster:
- Das erste Muster findet Pfade, bei denen die Übertragung von einem Konto zu einem gesperrten Konto über ein Zwischenkonto erfolgt.
- Das zweite Muster findet Pfade von einem Konto zur zugehörigen Person.
Die Variable interm dient als gemeinsame Verknüpfung zwischen den beiden Pfadmuster, sodass interm in beiden Pfadmuster auf denselben Elementknoten verweisen muss. Dadurch wird ein Equi-Join-Vorgang basierend auf der Variablen interm erstellt.
GRAPH FinGraph
MATCH
(src:Account)-[t1:Transfers]->(interm:Account)-[t2:Transfers]->(dst:Account),
(interm)<-[:Owns]-(p:Person)
WHERE dst.is_blocked = TRUE AND t1.amount > 200 AND t2.amount > 200
RETURN
src.id AS src_account_id, dst.id AS dst_account_id,
interm.id AS interm_account_id, p.id AS owner_id;
Hier sind die Abfrageergebnisse:
| src_account_id | dst_account_id | interm_account_id | owner_id |
|---|---|---|---|
| 20 | 16 | 7 | 1 |
Lineare Abfrageanweisungen
Sie können mehrere Graph-Anweisungen verketten, um eine lineare Abfrageanweisung zu bilden. Die Anweisungen werden in der Reihenfolge ausgeführt, in der sie in der Abfrage aufgeführt sind.
Jede Anweisung verwendet die Ausgabe der vorherigen Anweisung als Eingabe. Die Eingabe für die erste Anweisung ist leer.
Die Ausgabe der letzten Anweisung ist das Endergebnis.
Sie können beispielsweise lineare Abfrageanweisungen verwenden, um den maximalen Transfer auf ein gesperrtes Konto zu ermitteln. Mit der folgenden Abfrage werden das Konto und sein Inhaber mit der größten abgehenden Überweisung an ein gesperrtes Konto ermittelt.
GRAPH FinGraph
MATCH (src_account:Account)-[transfer:Transfers]->(dst_account:Account {is_blocked:true})
ORDER BY transfer.amount DESC
LIMIT 1
MATCH (src_account:Account)<-[owns:Owns]-(owner:Person)
RETURN src_account.id AS account_id, owner.name AS owner_name;
Die folgende Tabelle veranschaulicht diesen Prozess anhand der Zwischenergebnisse, die zwischen den einzelnen Anweisungen übergeben werden. Aus Gründen der Übersichtlichkeit werden nur einige Properties angezeigt.
| Aussage | Zwischenergebnis (abgekürzt) | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MATCH
(src_account:Account)
-[transfer:Transfers]->
(dst_account:Account {is_blocked:true})
|
|
||||||||||||
ORDER BY transfer.amount DESC |
|
||||||||||||
LIMIT 1 |
|
||||||||||||
MATCH
(src_account:Account)
<-[owns:Owns]-
(owner:Person)
|
|
||||||||||||
RETURN
src_account.id AS account_id,
owner.name AS owner_name
|
|
Hier sind die Abfrageergebnisse:
| Die Konto-ID von Tinfoil Security | owner_name |
|---|---|
7 |
Alex |
return-Anweisung
Mit der RETURN-Anweisung wird angegeben, was aus den übereinstimmenden Mustern zurückgegeben werden soll. Sie kann auf Variablen für das Diagrammmuster zugreifen und Ausdrücke und andere Klauseln wie ORDER BY und GROUP BY enthalten.
Spanner Graph unterstützt nicht die Rückgabe von Grafikelementen als Abfrageergebnisse. Wenn Sie das gesamte Grafikelement zurückgeben möchten, verwenden Sie die Funktion TO_JSON oder die Funktion SAFE_TO_JSON.
Von diesen beiden Funktionen empfehlen wir die Verwendung von SAFE_TO_JSON.
Graphelemente als JSON zurückgeben
GRAPH FinGraph
MATCH (n:Account {id: 7})
-- Returning a graph element in the final results is NOT allowed. Instead, use
-- the TO_JSON function or explicitly return the graph element's properties.
RETURN TO_JSON(n) AS n;
GRAPH FinGraph
MATCH (n:Account {id: 7})
-- Certain fields in the graph elements, such as TOKENLIST, can't be returned
-- in the TO_JSON function. In those cases, use the SAFE_TO_JSON function instead.
RETURN SAFE_TO_JSON(n) AS n;
Hier sind die Abfrageergebnisse:
| n |
|---|
{"identifier":"mUZpbkdyYXBoLkFjY291bnQAeJEO","kind":"node","labels":["Account"],"properties":{"create_time":"2020-01-10T14:22:20.222Z","id":7,"is_blocked":false,"nick_name":"Vacation
Fund"}} |
Größere Abfragen mit dem Keyword NEXT erstellen
Sie können mehrere lineare Graphabfrageanweisungen mit dem Schlüsselwort NEXT verketten.
Die erste Anweisung erhält eine leere Eingabe und die Ausgabe jeder nachfolgenden Anweisung wird zur Eingabe für die nächste.
Im folgenden Beispiel wird der Inhaber des Kontos mit den meisten eingehenden Überweisungen ermittelt, indem mehrere lineare Graphanweisungen verkettet werden. Sie können dieselbe Variable, z. B. account, verwenden, um in mehreren linearen Anweisungen auf dasselbe Grafikelement zu verweisen.
GRAPH FinGraph
MATCH (:Account)-[:Transfers]->(account:Account)
RETURN account, COUNT(*) AS num_incoming_transfers
GROUP BY account
ORDER BY num_incoming_transfers DESC
LIMIT 1
NEXT
MATCH (account:Account)<-[:Owns]-(owner:Person)
RETURN account.id AS account_id, owner.name AS owner_name, num_incoming_transfers;
Hier sind die Abfrageergebnisse:
| Die Konto-ID von Tinfoil Security | owner_name | num_incoming_transfers |
|---|---|---|
16 |
Lee |
3 |
Funktionen und Ausdrücke
Sie können alle GoogleSQL-Funktionen (sowohl Aggregat- als auch Skalarfunktionen), Operatoren und bedingten Ausdrücke in Spanner Graph-Abfragen verwenden. Spanner Graph unterstützt auch grafische Funktionen und Operatoren.
Integrierte Funktionen und Operatoren
Die folgenden Funktionen und Operatoren werden in GQL verwendet:
PROPERTY_EXISTS(n, birthday): Gibt zurück, obndie Propertybirthdayhat.LABELS(n): Gibt die Labels vonnzurück, wie im Diagrammschema definiert.PROPERTY_NAMES(n): Gibt die Attributnamen vonnzurück.TO_JSON(n): Gibtnim JSON-Format zurück. Weitere Informationen finden Sie unterTO_JSON-Funktion.
das PROPERTY_EXISTS-Prädikat, die LABELS-Funktion und die TO_JSON-Funktion sowie andere integrierte Funktionen wie ARRAY_AGG und CONCAT.
GRAPH FinGraph
MATCH (person:Person)-[:Owns]->(account:Account)
RETURN person, ARRAY_AGG(account.nick_name) AS accounts
GROUP BY person
NEXT
RETURN
LABELS(person) AS labels,
TO_JSON(person) AS person,
accounts,
CONCAT(person.city, ", ", person.country) AS location,
PROPERTY_EXISTS(person, is_blocked) AS is_blocked_property_exists,
PROPERTY_EXISTS(person, name) AS name_property_exists
LIMIT 1;
Hier sind die Abfrageergebnisse:
| is_blocked_property_exists | name_property_exists | Labels | Konten | Standort | Person |
|---|---|---|---|---|---|
false |
true |
Person |
["Vacation Fund"] |
Adelaide, Australia |
{"identifier":"mUZpbkdyYXBoLlBlcnNvbgB4kQI=","kind":"node","labels":["Person"],"properties":{"birthday":"1991-12-21T08:00:00Z","city":"Adelaide","country":"Australia","id":1,"name":"Alex"}} |
Unterabfragen
Eine Unterabfrage ist eine Abfrage, die in einer anderen Abfrage verschachtelt ist. In den folgenden Listen sind die Regeln für Spanner Graph-Unterabfragen aufgeführt:
- Eine Unterabfrage wird in geschweifte Klammern
{}gesetzt. - Eine Unterabfrage kann mit der führenden
GRAPH-Klausel beginnen, um den relevanten Graphen anzugeben. Der angegebene Graph muss nicht mit dem in der äußeren Abfrage verwendeten Graph übereinstimmen. - Wenn die
GRAPH-Klausel in der Unterabfrage weggelassen wird, geschieht Folgendes:- Der Graph im Bereich wird aus dem nächstgelegenen äußeren Abfragekontext abgeleitet.
- Die Unterabfrage muss mit einer Anweisung für den Abgleich von Diagrammmustern mit
MATCHbeginnen.
- Eine Graphmustervariable, die außerhalb des Unterabfragebereichs deklariert wurde, kann nicht noch einmal innerhalb der Unterabfrage deklariert werden. Sie kann jedoch in Ausdrücken oder Funktionen innerhalb der Unterabfrage referenziert werden.
Gesamtzahl der Übertragungen von jedem Konto mit einer Unterabfrage ermitteln
Die folgende Abfrage veranschaulicht die Verwendung der Unterabfrage VALUE. Die Unterabfrage wird in geschweifte Klammern {} eingeschlossen, denen das Keyword VALUE vorangestellt ist. Die Abfrage gibt die Gesamtzahl der Übertragungen zurück, die von einem Konto aus initiiert wurden.
GRAPH FinGraph
MATCH (p:Person)-[:Owns]->(account:Account)
RETURN p.name, account.id AS account_id, VALUE {
MATCH (a:Account)-[transfer:Transfers]->(:Account)
WHERE a = account
RETURN COUNT(transfer) AS num_transfers
} AS num_transfers;
Hier sind die Abfrageergebnisse:
| Name | Die Konto-ID von Tinfoil Security | num_transfers |
|---|---|---|
Alex |
7 |
2 |
Dana |
20 |
2 |
Lee |
16 |
1 |
Eine Liste der unterstützten Unterabfrageausdrücke finden Sie unter Spanner Graph-Unterabfragen.
Mit einer Unterabfrage Konten finden, deren Inhaber die einzelnen Personen sind
In der folgenden Abfrage wird die CALL-Anweisung mit einer Inline-Unterabfrage verwendet. Mit der Anweisung MATCH
(p:Person) wird eine Tabelle mit einer einzelnen Spalte namens p erstellt.
Jede Zeile in dieser Tabelle enthält einen Person-Knoten. Mit der CALL (p)-Anweisung wird die eingeschlossene Unterabfrage für jede Zeile in dieser Arbeitstabelle ausgeführt. Mit der Unterabfrage werden Konten gefunden, die jeder übereinstimmenden Person gehören p. Mehrere Konten für dieselbe Person werden nach Konto-ID sortiert.
Im Beispiel wird die Knotenvariable p mit dem äußeren Gültigkeitsbereich aus der MATCH
(p:Person)-Klausel deklariert. Die CALL (p)-Anweisung verweist auf diese Variable. Mit dieser Deklaration können Sie die Knotenvariable in einem Pfadmuster der Unterabfrage neu deklarieren oder mehrfach deklarieren. So wird sichergestellt, dass die Variablen für den inneren und äußeren p-Knoten an denselben Person-Knoten im Diagramm gebunden werden. Wenn mit der CALL-Anweisung die Knotenvariable p nicht deklariert wird, behandelt die Unterabfrage die neu deklarierte Variable p als neue Variable. Diese neue Variable ist unabhängig von der Variable mit dem äußeren Bereich und die Unterabfrage deklariert sie nicht mehrfach, da sie unterschiedliche Ergebnisse zurückgibt. Weitere Informationen finden Sie in der Anweisung CALL.
GRAPH FinGraph
MATCH (p:Person)
CALL (p) {
MATCH (p)-[:Owns]->(a:Account)
RETURN a.Id AS account_Id
ORDER BY account_Id
}
RETURN p.name AS person_name, account_Id
ORDER BY person_name, account_Id;
Ergebnis
| person_name | account_Id |
|---|---|
| Alex | 7 |
| Dana | 20 |
| Lee | 16 |
Suchparameter
Sie können Spanner Graph mit Parametern abfragen. Weitere Informationen finden Sie in der Syntax und unter Daten mit Parametern abfragen in den Spanner-Clientbibliotheken.
Die folgende Abfrage veranschaulicht die Verwendung von Abfrageparametern.
GRAPH FinGraph
MATCH (person:Person {id: @id})
RETURN person.name;
Diagramme und Tabellen zusammen abfragen
Sie können Graph-Abfragen in Verbindung mit SQL verwenden, um mit einer einzigen Anweisung auf Informationen aus Ihren Grafiken und Tabellen zuzugreifen.
Der Operator GRAPH_TABLE verwendet eine lineare Diagrammabfrage und gibt das Ergebnis in tabellarischer Form zurück, die in eine SQL-Abfrage eingebunden werden kann. Dank dieser Interoperabilität können Sie die Ergebnisse von Graph-Abfragen mit Nicht-Graph-Inhalten anreichern und umgekehrt.
Sie können beispielsweise eine CreditReports-Tabelle erstellen und einige Kreditberichte einfügen, wie im folgenden Beispiel gezeigt:
CREATE TABLE CreditReports (
person_id INT64 NOT NULL,
create_time TIMESTAMP NOT NULL,
score INT64 NOT NULL,
) PRIMARY KEY (person_id, create_time);
INSERT INTO CreditReports (person_id, create_time, score)
VALUES
(1,"2020-01-10 06:22:20.222", 700),
(2,"2020-02-10 06:22:20.222", 800),
(3,"2020-03-10 06:22:20.222", 750);
Anschließend können Sie bestimmte Personen durch den Abgleich von Diagrammmustern in GRAPH_TABLE identifizieren und die Ergebnisse der Diagrammabfrage mit der Tabelle CreditReports verknüpfen, um Kredit-Scores abzurufen.
SELECT
gt.person.id,
credit.score AS latest_credit_score
FROM GRAPH_TABLE(
FinGraph
MATCH (person:Person)-[:Owns]->(:Account)-[:Transfers]->(account:Account {is_blocked:true})
RETURN DISTINCT person
) AS gt
JOIN CreditReports AS credit
ON gt.person.id = credit.person_id
ORDER BY credit.create_time;
Hier sind die Abfrageergebnisse:
| person_id | latest_credit_score |
|---|---|
1 |
700 |
2 |
800 |
Nächste Schritte
Best Practices für das Optimieren von Anfragen