Questo documento descrive come eseguire query sui grafici delle proprietà in Spanner Graph. Gli esempi in questa sezione utilizzano lo schema del grafo creato in Configura ed esegui query su Spanner Graph, illustrato nel seguente diagramma:
Eseguire una query su Spanner Graph
Puoi eseguire query su Spanner Graph nei seguenti modi:
Nella console Google Cloud
Invia una query nella pagina Spanner Studio. Per accedere alla pagina Spanner Studio, fai clic su Spanner Studio nella pagina Panoramica del database o Panoramica della tabella. Per ulteriori informazioni su come accedere a Spanner Studio, consulta Gestire i dati utilizzando la console Google Cloud.
Lo strumento a riga di comando
gcloud spanner
Invia un comando utilizzando il comando
gcloud spanner databases execute-sql
.L'API REST di
executeSql
eexecuteStreamingSql
Le API RPC
ExecuteSql
eExecuteStreamingSql
Struttura delle query di Spanner Graph
Questa sezione descrive in dettaglio ogni componente della query.
L'esempio seguente illustra la struttura di base di una query di grafo Spanner.
Spanner Graph ti consente di creare più grafici all'interno di un database.
La query inizia specificando il grafico di destinazione, FinGraph
, utilizzando la clausola GRAPH
.
Corrispondenza di pattern dei grafici
La corrispondenza di pattern del grafico trova pattern specifici all'interno del grafico. I pattern più di base sono i pattern di elementi (pattern di nodi e pattern di bordi), che corrispondono agli elementi del grafico (rispettivamente nodi e bordi). Gli schemi di elementi possono essere composti in schemi di percorsi e schemi più complessi.
Pattern di nodi
Un pattern di nodi è un pattern che corrisponde ai nodi del grafico. Questo pattern comprende una coppia di parentesi che possono essere abbinate, che può optionally contiene una variabile di pattern grafico, un'espressione di etichetta e filtri delle proprietà.
Trovare tutti i nodi
La seguente query restituisce tutti i nodi del grafo. La variabile n
, chiamata
variabile pattern grafico, si lega ai nodi corrispondenti. In questo caso, il pattern
del nodo corrisponde a tutti i nodi del grafico.
GRAPH FinGraph
MATCH (n)
RETURN LABELS(n) AS label, n.id;
Risultato
La query restituisce label
e id
come segue:
etichetta | ID |
---|---|
Account | 7 |
Account | 16 |
Account | 20 |
Persona | 1 |
Persona | 2 |
Persona | 3 |
Trovare tutti i nodi con un'etichetta specifica
La seguente query corrisponde a tutti i nodi del grafo che hanno l'etichetta Person
.
La query restituisce le proprietà label
, id
e name
dei nodi corrispondenti.
GRAPH FinGraph
MATCH (p:Person)
RETURN LABELS(p) AS label, p.id, p.name;
Risultato
etichetta | ID | nome |
---|---|---|
Persona | 1 | Alex |
Persona | 2 | Dana |
Persona | 3 | Lee |
Trovare tutti i nodi corrispondenti a un'espressione di etichetta
Puoi creare un'espressione di etichetta con uno o più operatori logici.
La seguente query corrisponde a tutti i nodi del grafo che hanno l'etichetta Person
o Account
. L'insieme di proprietà esposte dalla variabile del pattern grafico n
è il superinsieme delle proprietà esposte dai nodi con l'etichetta Person
o Account
.
GRAPH FinGraph
MATCH (n:Person|Account)
RETURN LABELS(n) AS label, n.id, n.birthday, n.create_time;
- Nei risultati, tutti i nodi hanno la proprietà
id
. - I nodi corrispondenti all'etichetta
Account
hanno la proprietàcreate_time
, ma non la proprietàbirthday
. Per la proprietàbirthday
viene restituito unNULL
per questi nodi. - I nodi corrispondenti all'etichetta
Person
hanno la proprietàbirthday
, ma non la proprietàcreate_time
. Per la proprietàcreate_time
viene restituito un valoreNULL
per questi nodi.
Risultato
etichetta | ID | compleanno | create_time |
---|---|---|---|
Account | 7 | NULL | 2020-01-10T14:22:20.222Z |
Account | 16 | NULL | 2020-01-28T01:55:09.206Z |
Account | 20 | NULL | 2020-02-18T13:44:20.655Z |
Persona | 1 | 1991-12-21T08:00:00Z | NULL |
Persona | 2 | 1980-10-31T08:00:00Z | NULL |
Persona | 3 | 1986-12-07T08:00:00Z | NULL |
Per saperne di più sulle regole delle espressioni delle etichette, consulta Espressione dell'etichetta.
Trova tutti i nodi corrispondenti all'espressione dell'etichetta e al filtro delle proprietà
La seguente query abbina tutti i nodi del grafo che hanno l'etichetta Person
e la cui proprietà id
è uguale a 1
.
GRAPH FinGraph
MATCH (p:Person {id: 1})
RETURN LABELS(p) AS label, p.id, p.name, p.birthday;
Risultato
etichetta | ID | nome | compleanno |
---|---|---|---|
Persona | 1 | Alex | 1991-12-21T08:00:00Z |
Puoi utilizzare la clausola WHERE
per creare condizioni di filtro più complesse su etichette e proprietà.
La seguente query corrisponde a tutti i nodi del grafo che hanno l'etichetta Person
e la proprietà birthday
è precedente a 1990-01-10
.
GRAPH FinGraph
MATCH (p:Person WHERE p.birthday < '1990-01-10')
RETURN LABELS(p) AS label, p.name, p.birthday;
Risultato
etichetta | nome | compleanno |
---|---|---|
Persona | Dana | 1980-10-31T08:00:00Z |
Persona | Lee | 1986-12-07T08:00:00Z |
Pattern di bordi
Un pattern di archi abbina gli archi o le relazioni tra i nodi. I pattern di bordo sono chiusi tra parentesi quadre []
con i simboli -
, ->
o <-
per indicare le direzioni.
Analogamente ai pattern dei nodi, le variabili dei pattern di grafo vengono utilizzate per associarsi agli elementi di bordo corrispondenti.
Trova tutti gli spigoli con etichette corrispondenti
La seguente query restituisce tutti gli archi del grafo che hanno l'etichetta Owns
.
La variabile del pattern grafico e
è associata agli spigoli corrispondenti.
GRAPH FinGraph
MATCH -[e:Owns]->
RETURN e.id AS owner_id, e.account_id;
Risultato
owner_id | account_id |
---|---|
1 | 7 |
3 | 16 |
2 | 20 |
Trova tutti gli spigoli corrispondenti all'espressione dell'etichetta e al filtro della proprietà
Analogamente a un pattern di nodi, un pattern di edge può utilizzare espressioni di etichetta, specifica delle proprietà e clausole WHERE
, come mostrato nella query seguente. La query trova tutti gli spigoli etichettati con Owns
e con la proprietà create_time
in un periodo specificato.
GRAPH FinGraph
MATCH -[e:Owns WHERE e.create_time > '2020-01-14'
AND e.create_time < '2020-05-14']->
RETURN e.id AS owner_id, e.create_time, e.account_id;
Risultato
owner_id | create_time | account_id |
---|---|---|
2 | 2020-01-28T01:55:09.206Z | 20 |
3 | 2020-02-18T13:44:20.655Z | 16 |
Trovare tutti i bordi utilizzando qualsiasi pattern di bordo di direzione
Sebbene tutti gli archi in Spanner Graph siano diretti, puoi utilizzare il
any direction
pattern di archi -[]-
in una query per abbinare gli archi in entrambe le direzioni.
La seguente query trova tutti i trasferimenti in cui è coinvolto un account bloccato.
GRAPH FinGraph
MATCH (account:Account)-[transfer:Transfers]-(:Account)
WHERE account.is_blocked
RETURN transfer.order_number, transfer.amount;
Risultato
order_number | quantità |
---|---|
304330008004315 | 300 |
304120005529714 | 100 |
103650009791820 | 300 |
302290001255747 | 200 |
Pattern di percorso
Un modello di percorso viene creato alternando modelli di nodi e bordi.
Trovare tutti i percorsi da un nodo con filtri di etichette e proprietà specificati utilizzando un pattern di percorso
La seguente query trova tutti i trasferimenti a un account avviati da un account di proprietà di Person
con id
uguale a 2
.
Ogni risultato corrispondente rappresenta un percorso da Person
{id: 2}
attraverso un Account
collegato utilizzando l'elemento Owns
a un altro Account
utilizzando l'elemento Transfers
.
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;
Risultato
sender_id | from_id | to_id |
---|---|---|
2 | 20 | 7 |
2 | 20 | 16 |
Pattern di percorsi quantificati
Un pattern quantificato consente di ripetere un pattern in un intervallo specificato.
Corrispondenza a un pattern di spigoli quantificato
La seguente query trova tutti gli account di destinazione a uno a tre trasferimenti da un account di origine Account
con id
uguale a 7
, diverso da sé stesso.
Il pattern di bordo con il suffisso del quantificatore {1, 3}
.
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;
Risultato
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 |
L'esempio precedente utilizza la funzione ARRAY_LENGTH
per accedere al
group variable
e
. Per maggiori informazioni, consulta la variabile del gruppo di accesso.
Alcune righe dei risultati di esempio sono ripetute perché potrebbero esserci più percorsi tra la stessa coppia di account src
e dst
che corrispondono al pattern.
Corrispondenza a un pattern di percorso quantificato
La seguente query trova i percorsi tra i nodi Account
con uno o due bordi Transfers
tramite account intermedi bloccati.
Il pattern del percorso tra parentesi è quantificato e la clausola WHERE
viene utilizzata tra le parentesi per specificare le condizioni per il pattern ripetuto.
GRAPH FinGraph
MATCH
(src:Account)
((:Account)-[:Transfers]->(interm:Account) WHERE interm.is_blocked){1,2}
-[:Transfers]->(dst:Account)
RETURN src.id AS src_account_id, dst.id AS dst_account_id;
Risultato
src_account_id | dst_account_id |
---|---|
7 | 20 |
7 | 20 |
20 | 20 |
Variabili di gruppo
Una variabile del pattern grafico dichiarata in un pattern quantificato è considerata una variabile di gruppo quando viene acceduta al di fuori del pattern quantificato e si lega a un array di elementi grafici corrispondenti.
Puoi accedere a una variabile di gruppo come array in cui gli elementi del grafico vengono conservati nell'ordine in cui appaiono lungo i percorsi corrispondenti. Puoi aggregare una variabile di gruppo utilizzando l'aggregazione orizzontale.
Variabile gruppo di accesso
Nel seguente esempio, si accede alla variabile e
come segue:
- Una variabile del modello di grafo associata a un singolo bordo nella clausola
WHERE
e.amount > 100
(all'interno del modello quantificato). - Una variabile di gruppo associata a un array di elementi di bordo in
ARRAY_LENGTH(e)
nell'istruzioneRETURN
(al di fuori del pattern quantificato). - Una variabile di gruppo associata a un array di elementi di bordo, aggregata da
SUM(e.amount)
al di fuori del pattern quantificato. Questo è un esempio di aggregazione orizzontale.
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;
Risultato
src_account_id | path_length | total_amount | dst_account_id |
---|---|---|---|
7 | 1 | 300 | 16 |
7 | 2 | 600 | 20 |
Percorsi qualsiasi e Percorsi più brevi
Per limitare i percorsi corrispondenti in ogni gruppo di percorsi che condividono gli stessi nodi di origine e di destinazione, puoi utilizzare il prefisso di ricerca del percorso ANY
o ANY SHORTEST
.
Puoi applicare questi prefissi solo prima di un intero pattern di percorso e non puoi applicarli all'interno di parentesi.
Corrispondenza utilizzando QUALSIASI
La seguente query trova tutti gli account univoci raggiungibili che distano uno o due
Transfers
da un determinato nodo Account
.
Il prefisso di ricerca dei percorsi ANY
garantisce che venga restituito un solo percorso tra una coppia unica di nodi src
e dst
Account
. Nell'esempio seguente, anche se puoi raggiungere il nodo Account
con {id: 16}
in due percorsi diversi dal nodo Account
di origine, i risultati includono un solo percorso.
GRAPH FinGraph
MATCH ANY (src:Account {id: 7})-[e:Transfers]->{1,2}(dst:Account)
LET ids_in_path = ARRAY(SELECT e.to_id FROM UNNEST(e) AS e)
RETURN src.id AS src_account_id, dst.id AS dst_account_id, ids_in_path;
Risultato
src_account_id | dst_account_id | ids_in_path |
---|---|---|
7 | 16 | 16 |
7 | 20 | 16,20 |
Pattern di grafici
Un pattern di grafico è costituito da uno o più pattern di percorso separati da virgole ,
.
I pattern di grafo possono contenere una clausola WHERE
, che consente di accedere a tutte le variabili dei pattern di grafo nei pattern di percorso per formare condizioni di filtro. Ogni pattern
di percorso produce una raccolta di percorsi.
Corrispondenza utilizzando un pattern grafico
La seguente query identifica gli account intermedi e i relativi proprietari coinvolti in transazioni di importo superiore a 200, tramite le quali vengono trasferiti fondi da un account di origine a un account bloccato.
I seguenti pattern di percorso formano il pattern del grafico:
- Il primo pattern trova i percorsi in cui il trasferimento avviene da un account a un account bloccato utilizzando un account intermedio.
- Il secondo pattern trova i percorsi da un account alla persona che lo possiede.
La variabile interm
funge da collegamento comune tra i due pattern di percorso, il che richiede che interm
faccia riferimento allo stesso nodo elemento in entrambi i pattern di percorso. Questa
crea un'operazione di join equi sulla base della variabile interm
.
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;
Risultato
src_account_id | dst_account_id | interm_account_id | owner_id |
---|---|---|---|
20 | 16 | 7 | 1 |
Istruzioni di query lineari
Puoi concatenare più istruzioni grafo per formare un'istruzione di query lineare. Le istruzioni vengono eseguite nell'ordine in cui appaiono nella query.
- Ogni istruzione prende come input l'output dell'istruzione precedente. L'input è vuoto per la prima istruzione.
- L'output dell'ultima istruzione è il risultato finale.
Trovare il trasferimento massimo a un account bloccato
La seguente query trova l'account e il relativo proprietario con il trasferimento in uscita più elevato a un account bloccato.
GRAPH FinGraph
MATCH (src_account:Account)-[transfer:Transfers]->(dst_account:Account)
WHERE dst_account.is_blocked
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;
La seguente tabella illustra come vengono trasmessi i risultati intermedi alle istruzioni. Per brevità, vengono mostrate solo alcune proprietà dei risultati intermedi.
Affermazione | Risultato intermedio (abbreviato) | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MATCH (src_account:Account) -[transfer:Transfers]-> (dst_account:Account) WHERE dst_account.is_blocked |
|
||||||||||||
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 |
|
Risultato
account_id | owner_name |
---|---|
7 | Alex |
Dichiarazione return
L'istruzione Return definisce cosa restituire dai pattern corrispondenti. Può accedere alle variabili dei pattern di grafici, contenere espressioni e altre clausole come ORDER_BY,
GROUP_BY. Consulta la dichiarazione RETURN
.
Tieni presente che Spanner Graph non supporta la restituzione di elementi del grafico come risultati
delle query. Per restituire l'intero elemento grafico, utilizza la funzione TO_JSON
.
Restituire gli elementi del grafico come JSON
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;
Risultato
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"}} |
Creazione di query più grandi con la parola chiave AVANTI
Puoi concatenare più istruzioni di query lineari del grafo utilizzando la parola chiave NEXT
. L'input per la prima istruzione di query lineare è vuoto. L'output di ogni
istruzione di query lineare diventa l'input della successiva istruzione di query lineare.
L'esempio seguente trova il proprietario dell'account con il maggior numero di trasferimenti in entrata collegando tra loro più istruzioni lineari del grafico. Tieni presente che puoi utilizzare la stessa variabile, account
in questo esempio, per fare riferimento allo stesso elemento del grafico in più istruzioni lineari.
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;
Risultato
account_id | owner_name | num_incoming_transfers |
---|---|---|
16 | Lee | 3 |
Funzioni ed espressioni
Puoi utilizzare tutte le funzioni (sia aggregate che scalari), gli operatori e le espressioni condizionali di Google SQL nella query del grafo Spanner. Spanner Graph supporta anche funzioni e operatori specifici per i grafici.
Funzioni e operatori integrati
Le seguenti funzioni e operatori vengono comunemente utilizzati in GQL:
PROPERTY_EXISTS(n, birthday)
: indica sen
espone la proprietàbirthday
.LABELS(n)
: restituisce le etichette din
come definite nello schema del grafico.PROPERTY_NAMES(n)
: restituisce i nomi delle proprietà din
.TO_JSON(n)
: restituiscen
in formato JSON. Per ulteriori informazioni, consulta la funzioneTO_JSON
.
La seguente query illustra il predicato PROPERTY_EXISTS
, la funzione LABELS
e la funzione
TO_JSON
, nonché altre funzioni integrate come ARRAY_AGG
e
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;
Risultato
is_blocked_property_exists | name_property_exists | etichette | account | località | persona |
---|---|---|---|---|---|
falso | true | Persona | ["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"}} |
Sottoquery
Una sottoquery è una query nidificata in un'altra query. Di seguito sono elencate le regole per le sottoquery di Spanner Graph:
- Una sottoquery è racchiusa tra una coppia di parentesi graffe
{}
. - Una sottoquery potrebbe iniziare con la clausola
GRAPH
iniziale per specificare il grafo nell'ambito. Il grafo specificato non deve essere uguale a quello utilizzato nella query esterna. - Quando la clausola
GRAPH
viene omessa nella sottoquery, si verifica quanto segue:- Il grafico in ambito viene dedotto dal contesto della query esterna più vicino.
- La sottoquery deve iniziare da un'istruzione di corrispondenza del pattern di grafo
con
MATCH.
- Una variabile del pattern grafico dichiarata al di fuori dell'ambito della sottoquery non può essere dichiarata di nuovo all'interno della sottoquery, ma è possibile farvi riferimento in espressioni o funzioni all'interno della sottoquery.
Utilizza una sottoquery per trovare il numero totale di trasferimenti da ogni account
La seguente query illustra l'utilizzo della sottoquery VALUE
. La sottoquery è chiusa tra parentesi graffe {}
con prefisso della parola chiave VALUE
. La query restituisce l'importo totale
di trasferimenti avviati da un account.
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 SUM(transfer.amount) AS total_transfer
} AS total_transfer;
Risultato
nome | account_id | total_transfer |
---|---|---|
Alex | 7 | 400 |
Dana | 20 | 700 |
Lee | 16 | 300 |
Per un elenco delle espressioni delle sottoquery supportate, consulta Sottoquery di Spanner Graph.
Parametri di query
Puoi eseguire query su Spanner Graph con parametri. Per ulteriori informazioni, consulta la sintassi e scopri come eseguire query sui dati con i parametri nelle librerie client di Spanner.
La seguente query illustra l'utilizzo dei parametri di ricerca.
GRAPH FinGraph
MATCH (person:Person {id: @id})
RETURN person.name;
Eseguire query su grafici e tabelle contemporaneamente
Puoi utilizzare le query sui grafici in combinazione con SQL per accedere alle informazioni dei tuoi grafici e delle tue tabelle in un'unica istruzione.
GRAPH_TABLE
L'operatore GRAPH_TABLE
prende una query sul grafico lineare e restituisce il risultato in un formato tabulare che può essere integrato perfettamente in una query SQL. Questa interoperabilità ti consente di arricchire i risultati delle query sui grafici con contenuti non grafici e viceversa.
Ad esempio, puoi creare una tabella CreditReports
e inserire alcuni report sul credito, come mostrato nell'esempio seguente:
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);
Quindi, identifica le persone di interesse tramite la corrispondenza dei pattern del grafico in GRAPH_TABLE
e unisci i risultati della query del grafico con la tabella CreditReports
per accedere al
voto di credito.
SELECT
gt.person.id,
credit.score AS latest_credit_score
FROM GRAPH_TABLE(
FinGraph
MATCH (person:Person)-[:Owns]->(:Account)-[:Transfers]->(account:Account)
WHERE account.is_blocked
RETURN DISTINCT person
) AS gt
JOIN CreditReports AS credit
ON gt.person.id = credit.person_id
ORDER BY credit.create_time;
Risultato:
person_id | latest_credit_score |
---|---|
1 | 700 |
2 | 800 |
Passaggi successivi
Scopri le best practice per l'ottimizzazione delle query.