Panoramica delle query di Spanner Graph

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:

Esempio di schema di Spanner Graph.

Eseguire una query su Spanner Graph

Puoi eseguire query su Spanner Graph nei seguenti modi:

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.

Esempio di struttura di query di Spanner Graph.

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 un NULL 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 valore NULL 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'istruzione RETURN (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
src_account Trasferimento dst_account
{id: 7} {amount: 300.0} {id: 16, is_blocked: true}
{id: 7} {amount: 100.0} {id: 16, is_blocked: true}
{id: 20} {amount: 200.0} {id: 16, is_blocked: true}

ORDER BY transfer.amount DESC
src_account Trasferimento dst_account
{id: 7} {amount: 300.0} {id: 16, is_blocked: true}
{id: 20} {amount: 200.0} {id: 16, is_blocked: true}
{id: 7} {amount: 100.0} {id: 16, is_blocked: true}

LIMIT 1
src_account Trasferimento dst_account
{id: 7} {amount: 300.0} {id: 16, is_blocked: true}

MATCH
  (src_account:Account)
    <-[owns:Owns]-
  (owner:Person)
src_account Trasferimento dst_account possiede owner
{id: 7} {amount: 300.0} {id: 16, is_blocked: true} {person_id: 1, account_id: 7} {id: 1, name: Alex}

RETURN
  src_account.id AS account_id,
  owner.name AS owner_name
account_id owner_name
7 Alex

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 se n espone la proprietà birthday.
  • LABELS(n): restituisce le etichette di n come definite nello schema del grafico.
  • PROPERTY_NAMES(n): restituisce i nomi delle proprietà di n.
  • TO_JSON(n): restituisce n in formato JSON. Per ulteriori informazioni, consulta la funzione TO_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.