Guida al linguaggio GQL per graph in Microsoft Fabric

GQL (Graph Query Language) è il linguaggio di query standardizzato ISO per i database a grafo. Usare GQL per eseguire query, analizzare e usare i dati del grafo in modo efficiente con il grafico in Microsoft Fabric.

Lo stesso gruppo di lavoro ISO che standardizza SQL sviluppa GQL. Di conseguenza, GQL condivide molti concetti con SQL, tra cui espressioni, predicati e tipi di dati. Se si ha esperienza con SQL, è possibile applicare gran parte di queste conoscenze a GQL.

Questo articolo è la guida end-to-end al GQL in grafico. Spiega come il linguaggio si integra e collega a riferimenti focalizzati per una sintassi completa e dettagli di tipo. Si tratta di:

  • Concetti di base: strutture dei dati, modelli e nozioni fondamentali sulle query del grafo
  • Enunciati essenziali: MATCH, FILTER, LET, WHEN, ORDER BY, LIMIT, e RETURN
  • Tipi di dati ed espressioni: tipi di valore, operatori e funzioni predefinite
  • Tecniche avanzate: composizione con più istruzioni, definizione dell'ambito delle variabili e strategie di aggregazione

Annotazioni

Lo standard internazionale ufficiale per GQL è ISO/IEC 39075 Information Technology - Linguaggi di database - GQL.

Se cerchi indicazioni orientate al compito invece di una guida linguistica, consulta le guide pratiche:

Usa gli articoli di riferimento focalizzati quando hai bisogno di dettagli completi:

Informazioni necessarie Articolo definitivo
Sintassi a colpo d'occhio Informazioni di riferimento rapido su GQL
Sintassi di composizione di nodi, archi, cammini e pattern Modelli di grafo GQL
Operatori, predicati e funzioni Espressioni, predicati e funzioni GQL
Sintassi letterale, comportamento dei valori e conversioni di tipo Valori e tipi valore GQL
Definizioni e vincoli dei tipi di grafo Tipi di grafo GQL
Copertura attuale delle funzionalità ISO GQL Conformità allo standard GQL
Restrizioni e limiti attuali specifici per Fabric Limitazioni correnti

Prerequisiti

Prima di iniziare, assicurarsi di avere familiarità con questi concetti:

  • Informità basata sui database - Esperienza con qualsiasi sistema di database, ad esempio relazionale (SQL), NoSQL o grafico è utile.
  • Concetti relativi ai grafici: informazioni su nodi, archi e relazioni nei dati connessi.
  • Nozioni fondamentali sulle query : conoscenza dei concetti di base delle query, ad esempio il filtro, l'ordinamento e l'aggregazione.

Sfondo consigliato:

  • L'esperienza con i linguaggi SQL o openCypher semplifica l'apprendimento della sintassi GQL (sono radici di GQL).
  • La familiarità con la modellazione dei dati è utile per la progettazione dello schema del grafo.
  • Informazioni sul caso d'uso specifico per i dati del grafo.

Elementi necessari:

  • Accesso a un'area di lavoro graph con funzionalità di query.
  • Dati di esempio o disponibilità a lavorare con i nostri esempi di social network.
  • Editor di testo di base per la scrittura di query.

Suggerimento

Se non si ha familiarità con i database a grafo, iniziare con la panoramica dei modelli di dati del grafo prima di continuare con questa guida.

Cosa rende GQL speciale

GQL è progettato specificamente per i dati di grafo, quindi la sua sintassi esprime direttamente come le entità sono connesse. Dove SQL esprime comunemente le relazioni tramite joins tra tabelle, GQL utilizza pattern grafici che assomigliano a diagrammi dei dati.

Ad esempio, la seguente query trova coppie di persone che si conoscono e che sono nate entrambe prima del 1999:

MATCH (person:Person)-[:knows]-(friend:Person)
WHERE person.birthday < 19990101
  AND friend.birthday < 19990101
RETURN person.firstName || ' ' || person.lastName AS person_name,
       friend.firstName || ' ' || friend.lastName AS friend_name

Il pattern (person:Person)-[:knows]-(friend:Person) mostra la struttura delle relazioni per corrispondere. Le variabili legano le due persone così che la query possa filtrare e restituire le loro proprietà.

Nozioni fondamentali su GQL

Questi concetti costituiscono la base del GQL:

  • I grafi contengono nodi e archi con etichette e proprietà.
  • I tipi di grafo definiscono formalmente i tipi di nodo, i tipi di spigoli e i vincoli consentiti in un grafo.
  • Le query utilizzano istruzioni come MATCH, FILTER, e RETURN per elaborare dati e produrre risultati.
  • I pattern descrivono le strutture dei grafi per corrispondere.
  • Le espressioni calcolano, trasformano e confrontano i valori.
  • I predicati sono espressioni booleane usate per testare le condizioni.
  • I tipi di valore definiscono i tipi di valori che le query possono elaborare e le proprietà del grafo possono memorizzare.

Comprendere i dati dei grafi

Per lavorare con GQL, devi comprendere la struttura del grafo di proprietà etichettata che il linguaggio interroga.

Nodi e archi: blocchi predefiniti

Un grafo di proprietà etichettato contiene due tipi di elementi del grafo:

  • I nodi tipicamente rappresentano entità, come persone, organizzazioni, post o prodotti.
  • Gli archi rappresentano connessioni tra nodi, come quando una persona conosce un'altra persona o lavora in un'azienda.

Ogni elemento del grafo ha un'identità interna, una o più etichette e un insieme di proprietà. Le etichette classificano elementi, come Person o knows. Le proprietà sono coppie nome-valore, come firstName: 'Alice' o birthday: 19730108u. In Graph, un arco ha sempre esattamente un'etichetta.

Ogni arco collega esattamente due nodi: un'origine e un bersaglio. La direzione del bordo fa parte della struttura del grafo. Ad esempio, un workAt bordo può collegare un'origine Person a un Company bersaglio.

Annotazioni

Attualmente Graph non supporta la creazione di archi non orientati. Puoi interrogare un arco diretto esistente in entrambe le direzioni usando un pattern di archi orientati qualsiasi come -[:knows]-.

I grafi sono ben formati: ogni arco collega due nodi che esistono nello stesso grafo.

Modelli a grafo e tipi di grafo

Un modello di grafo Fabric definisce i tipi di nodi, i tipi di argo, le proprietà, le mappature sorgente e le chiavi disponibili in un grafo. Specifica quali righe della tabella sorgente diventano nodi e archi e come questi elementi si collegano. Per indicazioni sulla modellazione, vedi Progettare uno schema di grafo.

Lo standard GQL utilizza un tipo di grafo per descrivere formalmente i tipi di nodi consentiti, i tipi di archi, le proprietà e i vincoli. I tipi di grafo sono la controparte a livello linguistico della struttura rappresentata da un modello di grafo Fabric, ma attualmente Graf non accetta direttamente dichiarazioni di tipo grafo GQL. Per la sintassi formale e i concetti, vedi tipi di grafo GQL.

Esempio di grafo usato in questa guida

Gli esempi utilizzano il dataset campione dei social network, che include persone, luoghi, organizzazioni, messaggi, tag e i bordi che li collegano.

Il grafico campione collega queste aree:

  • Le persone conoscono altre persone, lavorano in aziende e studiano all'università.
  • Città, paesi o regioni, e continenti formano una gerarchia geografica.
  • I forum contengono post, e le persone creano post e commenti.
  • I tag categorizzano i contenuti e rappresentano gli interessi delle persone.

Diagramma che mostra lo schema del social network.

Per la struttura completa dell'esempio, vedi l'esempio dello schema dei social network. Per concetti generali di grafo, vedi Grafi con proprietà etichettate.

Le prime query GQL

Dopo aver appreso le nozioni di base sul grafo, vedere come eseguire query sui dati del grafo usando GQL. Questi esempi vengono compilati da semplici a complessi, che illustrano come l'approccio di GQL rende le query del grafo intuitive e potenti.

Iniziare con semplicità: trovare tutte le persone

Iniziare con la query più semplice possibile. Trovare i nomi (nome, cognome) di tutte le persone (:Persons) nel grafico.

MATCH (p:Person)
RETURN p.firstName, p.lastName

Questa query viene eseguita nel modo seguente:

  1. MATCH trova tutti i nodi con etichetta Person.
  2. RETURN mostra il nome e il cognome.

Aggiungi filtro: trovare persone specifiche

Ora trovare persone con caratteristiche specifiche. In questo caso, trovare tutti i nomi di Alice e mostrare i loro nomi e compleanni.

MATCH (p:Person)
FILTER p.firstName = 'Alice'
RETURN p.firstName, p.lastName, p.birthday

Questa query viene eseguita nel modo seguente:

  1. MATCH trova tutti i nodi (p) etichettati Person.
  2. FILTER nodi (p) il cui nome è Alice.
  3. RETURN mostra il nome, il cognome e il compleanno.

Struttura di query di base

Tutte le query GQL di base seguono un modello coerente: una sequenza di istruzioni che interagiscono per trovare, filtrare e restituire dati. La maggior parte delle query inizia con MATCH trovare i pattern nel grafico e termina con RETURN specificare l'output.

Ecco una semplice query che trova coppie di persone che si conoscono e condividono la stessa data di nascita, poi restituisce il conteggio totale di quelle coppie di amici.

MATCH (n:Person)-[:knows]-(m:Person)
FILTER n.birthday = m.birthday
RETURN count(*) AS same_age_friends

Questa query viene eseguita nel modo seguente:

  1. MATCH trova tutte le coppie di Person nodi che si conoscono tra loro.
  2. FILTER mantiene solo le coppie in cui entrambe le persone hanno lo stesso compleanno.
  3. RETURN conta quante coppie di amici esistono.

Suggerimento

Puoi anche filtrare direttamente in un pattern aggiungendo una WHERE clausola. Ad esempio, MATCH (n:Person WHERE n.birthday < 19900101) abbina solo Person i nodi con un birthday valore precedente al 1990.

GQL supporta commenti di linea in stile // C, commenti di linea in stile -- SQL e commenti di blocco in stile /* */ C.

Affermazioni comuni

  • MATCH: Identifica il pattern grafico da cercare—qui si definisce la struttura dei dati che ti interessano.
  • LET: Assegna nuove variabili o valori calcolati basandosi su dati corrispondenti—aggiunge colonne derivate al risultato.
  • FOR: Espande una lista in righe, con un offset opzionale basato su zero o una posizione ordinale basata su uno.
  • CALL: Esegue una sottoquery inline per ogni riga di input e aggiunge le colonne restituite dalla sottoquery.
  • FILTER: Restringe i risultati applicando condizioni—rimuove le righe che non soddisfano i criteri.
  • ORDER BY: Ordina i dati filtrati—aiuta a organizzare l'output in base a uno o più campi.
  • OFFSET e LIMIT: Limitare il numero di righe restituite—utile per la paginazione o per query top-k.
  • RETURN: Specifica l'output finale—definisce quali dati devono essere inclusi nell'insieme di risultati ed esegue l'aggregazione.
  • NEXT: Avvia un'altra fase di query utilizzando le colonne restituite dalla fase precedente.

Come interagiscono le istruzioni

Le istruzioni GQL formano una pipeline, in cui ogni istruzione elabora l'output della precedente. Questa esecuzione sequenziale rende le query facili da leggere e debugare perché l'ordine di esecuzione corrisponde a quello di lettura.

Punti chiave:

  • Le istruzioni vengono eseguite in modo effettivo sequenziale.
  • Ogni istruzione trasforma i dati e li trasmette al successivo.
  • Questo processo crea un flusso di dati chiaro e prevedibile che semplifica query complesse.
  • NEXT Inizia una nuova fase di interrogazione. Solo le colonne proiettate dall'affermazione RETURN precedente sono disponibili nella fase successiva.
  • UNION, UNION DISTINCT, e UNION ALL combinare i risultati dei blocchi completi di interrogazione.

Annotazioni

Le istruzioni hanno un ordine logico definito. Scrivi query in base a questo flusso di dati invece di affidarti a una particolare strategia di esecuzione fisica.

Esempio di composizione delle istruzioni

La seguente query GQL trova le prime 10 persone che lavorano in aziende con "Air" nel nome, le ordina per nome completo e restituisce il nome completo insieme al nome delle loro aziende.

-- Data flows: Match → Let → Filter → Order → Limit → Return
MATCH (p:Person)-[:workAt]->(c:Company)           -- Input: unit table, Output: (p, c) table
LET fullName = p.firstName || ' ' || p.lastName   -- Input: (p, c) table, Output: (p, c, fullName) table
FILTER c.name CONTAINS 'Air'                      -- Input: (p, c, fullName) table, Output: filtered table
ORDER BY fullName                                 -- Input: filtered table, Output: sorted table
LIMIT 10                                          -- Input: sorted table, Output: top 10 rows table
RETURN fullName, c.name AS companyName            -- Input: top 10 rows table
                                                  -- Output: projected (fullName, companyName) result table

Questa query viene eseguita nel modo seguente:

  1. MATCH Trova persone che lavorano in aziende.
  2. LET crea nomi completi combinando nomi di prima e famiglia.
  3. FILTER tiene solo i dipendenti delle aziende con "Air" nel nome aziendale.
  4. ORDER BY ordina in base al nome completo.
  5. LIMIT accetta i primi 10 risultati.
  6. RETURN restituisce nomi completi e nomi aziendali.

Le variabili connettono i dati

Le variabili, ad esempio p, ce fullName negli esempi precedenti, contengono dati tra istruzioni. Quando si riutilizza un nome di variabile, GQL garantisce automaticamente che faccia riferimento agli stessi dati, creando condizioni di join avanzate. Le variabili sono talvolta denominate anche variabili di associazione.

È possibile classificare le variabili in modi diversi:

Per origine dell'associazione:

  • Variabili di criterio: associate da modelli di grafo corrispondenti
  • Variabili regolari : associate da altri costrutti di linguaggio

Tipi di variabile modello:

  • Variabili di elemento : associazione ai valori di riferimento degli elementi del grafo
    • Variabili del nodo : associazione a singoli nodi
    • Variabili di arco : associazione a singoli bordi
  • Variabili di percorso : eseguire l'associazione ai valori di percorso che rappresentano percorsi corrispondenti

Per grado di riferimento:

  • Variabili singleton : associazione a singoli valori di riferimento di elementi dai modelli
  • Variabili di gruppo - associarsi a elenchi di valori di riferimento degli elementi da pattern a lunghezza variabile. Per dettagli, vedi Funzioni aggregate.

Risultati e risultati dell'esecuzione

Quando si esegue una query, si ottiene un risultato di esecuzione costituito da:

  • Un risultato, normalmente una tabella dei risultati con i dati della tua RETURN dichiarazione.
  • Informazioni sullo stato che indicano se la query ha avuto esito positivo o negativo.

Tabelle dei risultati

La tabella dei risultati, se presente, è il risultato effettivo dell'esecuzione della query.

Una tabella dei risultati include informazioni sul nome e sul tipo delle relative colonne, una sequenza di nomi di colonna preferita da utilizzare per visualizzare i risultati, se la tabella è ordinata e le righe effettive stesse.

Annotazioni

Se l'esecuzione ha esito negativo, non viene inclusa alcuna tabella dei risultati nel risultato dell'esecuzione.

Risultati omessi

GQL definisce anche un risultato omesso per le affermazioni che non producono mai righe, indipendentemente dai dati o dall'esito della valutazione. Un risultato omesso ha codice 00001di stato di completamento con successo .

Un risultato omesso differisce da una tabella dei risultati vuota. Una tabella vuota significa che una query che produceva righe è stata valutata ma non ha prodotto righe. L'API di Query può rappresentare un risultato omesso con il tipo NOTHINGdi risultato .

Graph reserves ha omesso i risultati per il supporto futuro per il data definition language (DDL) e il data manipolation language (DML). Le istruzioni di query attuali producono risultati di tabelle, incluse tabelle vuote.

Informazioni sullo stato

Durante l'esecuzione della query, il processo rileva diverse condizioni degne di nota, ad esempio errori o avvisi. Ogni condizione viene registrata da un oggetto stato nelle informazioni sullo stato del risultato dell'esecuzione.

Le informazioni sullo stato sono costituite da un oggetto di stato primario e da un elenco (possibilmente vuoto) di altri oggetti di stato. L'oggetto di stato primario esiste sempre e indica se l'esecuzione della query ha avuto esito positivo o negativo.

Ogni oggetto di stato include un codice alfanumerico di cinque caratteri e una descrizione della condizione registrata.

L'API di Query utilizza i seguenti codici di stato primari:

Codice di stato API Meaning
00000 Completamento riuscito con almeno una riga.
00001 Completamento con successo con risultato omesso. Riservato per il supporto futuro DDL e DML.
01000 Un avvertimento o una condizione informativa.
02000 Attualmente non sono disponibili righe da una query che produce righe.
42000 Un errore di query correttibile dall'utente.
50000 Un errore di sistema o non classificato.

L'API preserva lo stato canonico GQL riportato dal motore di query nel _graphaneGqlStatus membro del record diagnostico. Ad esempio, il sovrapprezzo numerico usa lo status 22003canonico GQL , mentre la divisione per zero usa 22012; entrambi sono rappresentati da 42000 nel campo pubblico status.code .

Importante

Nel codice applicativo, usa status.code per il successo ampio e la gestione degli errori. Usa la diagnostica canonica GQLSTATUS quando devi distinguere una condizione specifica di interrogazione. Non testare il testo della descrizione perché può variare.

Inoltre, gli oggetti di stato possono contenere un oggetto stato della causa sottostante e un record di diagnostica con ulteriori informazioni che caratterizzano la condizione registrata.

Concetti e istruzioni essenziali

Questa sezione illustra i blocchi predefiniti di base necessari per scrivere query GQL efficaci. Ogni concetto si basa sulle competenze pratiche di scrittura delle query.

Pattern grafici: trovare la struttura

Un pattern a grafo descrive i nodi, gli archi e i percorsi da corrispondere. Binding variabili quando le istruzioni successive devono riferirsi a elementi abbinati:

MATCH (person:Person)-[employment:workAt]->(company:Company)
RETURN person.firstName, company.name, employment.workFrom

Posiziona un predicato in linea quando definisce quale nodo o arco può partecipare al pattern:

MATCH (person:Person WHERE person.firstName = 'Alice')
      -[:knows]->(friend:Person)
RETURN friend.firstName, friend.lastName

Riutilizza una variabile per richiedere due posizioni di pattern per associare lo stesso elemento. Separare i modelli con virgole per comporre strutture di grafo più grandi. Usa un quantificatore per {1,4} ripetere un pattern di spigoli e abbinare percorsi a lunghezza variabile.

Le modalità di percorso controllano il riutilizzo degli elementi all'interno di un percorso:

Modalità di percorso Behavior
WALK Consente nodi e bordi ripetuti. Questa modalità è l'impostazione predefinita.
TRAIL Previene spigoli ripetuti.
SIMPLE Previene la ripetizione dei nodi, tranne che per un primo e un ultimo nodo condivisi.
ACYCLIC Previene tutti i nodi ripetuti.

Un prefisso di ricerca di percorso determina quali percorsi corrispondenti vengono restituiti. ALL è l'impostazione predefinita. ANY SHORTEST restituisce un percorso più breve per ogni coppia sorgente-destinazione:

MATCH path = ANY SHORTEST
  (source:Person WHERE source.id = 123u)-[:knows]->{1,4}(target:Person)
RETURN target.id, path_length(path) AS hopCount

I predicati inline limitano l'idoneità al percorso prima della selezione del percorso. Le operazioni a livello MATCH ... WHERE di istruzione e successive FILTER sono postfiltri. Questa distinzione può cambiare ANY SHORTEST i risultati.

Per la semantica definitiva di nodo, archi, percorso, composizione, quantificatore e posizionamento dei predicati, vedi modelli grafici GQL. Per le restrizioni attuali del percorso, vedi Limitazioni attuali.

Istruzioni principali

GQL fornisce tipi di istruzioni specifici che interagiscono per elaborare i dati del grafo in modo dettagliato. Comprendere queste istruzioni è essenziale per creare query efficaci.

MATCH istruzione

Sintassi:

MATCH <graph pattern>, <graph pattern>, ... [ WHERE <predicate> ]

L'istruzione MATCH accetta i dati di input e trova i modelli di grafico. Unisce le variabili di input con variabili di modello e restituisce tutte le combinazioni corrispondenti.

Variabili di input e output:

-- Input: unit table (no columns, one row)
-- Pattern variables: p, c  
-- Output: table with (p, c) columns for each person-company match
MATCH (p:Person)-[:workAt]->(c:Company)

Filtro a livello di istruzione tramite WHERE:

-- Filter pattern matches
MATCH (p:Person)-[:workAt]->(c:Company) WHERE p.lastName = c.name

È possibile filtrare tutte le corrispondenze post-filtro usando WHERE. Questo approccio evita un'istruzione separata FILTER . Con un prefisso di ricerca di percorso come ANY SHORTEST, il livello WHERE di istruzione si applica dopo la selezione del percorso. I predicati inline invece vincolano quali percorsi sono ammissibili per la selezione. Per maggiori informazioni, vedi Posizionare predicati prima o dopo la selezione del percorso.

Join tramite variabili di input:

Quando MATCH non è la prima istruzione, unisce i dati di input con corrispondenze del criterio:

...
-- Input: table with 'targetCompany' column
-- Implicit join: targetCompany (equality join)
-- Output: table with (targetCompany, p, r) columns
MATCH (p:Person)-[r:workAt]->(targetCompany)

Importante

Graph supporta la composizione di istruzioni lineari di base e completa, inclusi NEXT. Puoi anche combinare i blocchi di query con UNION, UNION DISTINCT, e UNION ALL. Le EXCEPToperazioni , INTERSECT, e OTHERWISE set non sono ancora supportate. Per altre informazioni, vedere l'articolo sulle limitazioni correnti.

Comportamenti di join chiave:

Modalità di MATCH gestione dell'unione dei dati:

  • Uguaglianza delle variabili: join di variabili di input con variabili di modello usando la corrispondenza di uguaglianza
  • Inner join: le righe di input senza corrispondenze dei criteri vengono eliminate. Usare OPTIONAL MATCH per il comportamento left-outer-join.
  • Ordine di filtraggio: Filtri a livello WHERE di istruzione dopo il pattern matching e la selezione del percorso completata
  • Composizione del pattern: Le variabili condivise vincolano i pattern allo stesso elemento. I pattern disconnessi formano un prodotto cartesiano.

Importante

Un pattern disconnesso è valido, ma il suo prodotto cartesiano può creare molte righe. Usa variabili condivise quando i pattern dovrebbero riferirsi agli stessi elementi del grafo.

Modelli di join con variabili condivise:

-- Shared variable 'p' joins the two patterns
-- Output: people with both workplace and residence data
MATCH (p:Person)-[:workAt]->(c:Company), 
      (p)-[:isLocatedIn]->(city:City)

OPTIONAL MATCH istruzione

Sintassi:

OPTIONAL MATCH <graph pattern> [ WHERE <predicate> ]

OPTIONAL MATCH funziona come MATCH ma usa la semantica left-outer-join. Se il criterio non trova alcuna corrispondenza per una riga di input, la query mantiene la riga con NULL valori per le variabili non corrispondenti anziché eliminarla.

Esempio:

-- Find all people and, if available, their workplace
MATCH (p:Person)
OPTIONAL MATCH (p)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name AS company_name

Gli utenti che non lavorano in alcuna azienda vengono ancora visualizzati nei risultati con NULL per company_name.

Suggerimento

Usare OPTIONAL MATCH quando si desidera includere entità che potrebbero non avere una relazione specifica, simile a un OGGETTO SQL LEFT JOIN.

LET istruzione

Sintassi:

LET <variable> = <expression>, <variable> = <expression>, ...

L'istruzione LET crea variabili calcolate e abilita la trasformazione dei dati all'interno della pipeline di query.

Creazione di variabili di base:

MATCH (p:Person)
LET fullName = p.firstName || ' ' || p.lastName
RETURN *
LIMIT 1000

Calcoli complessi:

MATCH (p:Person)
LET adjustedAge = 2000 - (p.birthday / 10000),
    fullProfile = p.firstName || ' ' || p.lastName || ' (' || p.gender || ')'
RETURN *
LIMIT 1000

Comportamenti principali:

  • Il motore di query valuta le espressioni per ogni riga di input.
  • I risultati diventano nuove colonne nella tabella di output.
  • Le variabili possono fare riferimento solo alle variabili esistenti delle istruzioni precedenti.
  • Più assegnazioni in una LET stessa istruzione usano lo stesso ambito di input, quindi un'assegnazione non può fare riferimento a un'altra assegnazione da quella sentenza.

FOR istruzione

Sintassi:

FOR <variable> IN <list_expression>
  [ WITH OFFSET <offset_variable> | WITH ORDINALITY <ordinality_variable> ]

La FOR dichiarazione espande un elenco in righe. Per ogni riga di input, emette una riga di output per ogni elemento della lista e lega quell'elemento alla variabile specificata. Altre variabili della riga di input rimangono disponibili.

Usa WITH OFFSET per associare un indice basato su zero, o WITH ORDINALITY usa per associare una posizione basata su uno.

LET cities = ['Seattle', 'London', 'Tokyo']
FOR city IN cities WITH ORDINALITY position
RETURN city, position

Questa query restituisce una riga per ogni città. I position valori sono 1, 2, e 3. Se si sostituisce WITH ORDINALITY position con WITH OFFSET position, i valori sono 0, 1, e 2.

L'espressione sorgente deve valutare su una lista. Un valore non di elenco causa il fallimento della query.

CALL istruzione

Usare CALL per eseguire una sottoquery inline per ogni riga di input:

CALL {
  <query statements>
  RETURN <columns>
}

Le variabili già nell'ambito sono implicitamente disponibili all'interno della sottoquery. Delle variabili create all'interno della sottoquery, solo le colonne della sua istruzione finale RETURN diventano disponibili al di fuori di essa. Le variabili create all'interno della sottoquery ma non restituite rimangono locali.

La seguente sottoquery correlata calcola il conteggio del datore di lavoro per ogni persona:

MATCH (p:Person)
CALL {
  MATCH (p)-[:workAt]->(company:Company)
  RETURN count(*) AS employerCount
}
RETURN p.firstName, p.lastName, employerCount
ORDER BY employerCount DESC

Un ordinario CALL agisce come una giunzione interna dipendente. Produce una riga di output per ogni riga restituita dalla sottoquery. Se la sottoquery non restituisce righe, la riga esterna corrispondente non viene restituita. Se restituisce più righe, la riga esterna appare una volta per ogni riga di sottoquery.

L'esempio precedente count(*) restituisce sempre una riga di sottoquery perché utilizza un aggregato non raggruppato. Una persona senza datore di lavoro corrispondente ha quindi un employerCount valore di 0.

Usare OPTIONAL CALL come join sinistro dipendente. Quando la sottoquery non restituisce righe, preserva una riga esterna e imposta le colonne della sottoquery restituite a NULL. Quando la sottoquery restituisce più righe, produce una riga di output per ogni riga della sottoquery.

MATCH (p:Person)
OPTIONAL CALL {
  MATCH (p)-[:workAt]->(company:Company)
  RETURN company.name AS companyName
}
RETURN p.firstName, p.lastName, companyName

Puoi annidare sottoquery inline CALL . Una sottoquery annidata può fare riferimento a variabili dai suoi ambiti di query che racchiudono.

Importante

Termina ogni corpo in linea CALL con RETURN. Graph non supporta chiamate a procedure nominate né liste esplicite di importazione di variabili come CALL (p) { ... }.

FILTER istruzione

Sintassi:

FILTER [ WHERE ] <predicate>

L'istruzione FILTER fornisce un controllo preciso sui dati che procedono attraverso la pipeline di query.

Filtro di base:

MATCH (p:Person)
FILTER p.birthday < 19980101 AND p.gender = 'female'
RETURN *

Condizioni logiche complesse:

MATCH (p:Person)
FILTER (p.gender = 'male' AND p.birthday < 19940101) 
  OR (p.gender = 'female' AND p.birthday < 19990101)
  OR p.browserUsed = 'Edge'
RETURN *

Modelli di filtro con riconoscimento dei valori Null:

Usare questi modelli per gestire i valori Null in modo sicuro:

  • Verificare la presenza di valori: - p.firstName IS NOT NULL ha un nome
  • Convalidare i dati: p.id > 0 - ID valido
  • Gestire i dati mancanti: NOT coalesce(p.locationIP, '10.x.x.x') STARTS WITH '10.x.x.x' - Non è stato eseguito la connessione dalla rete locale
  • Combinare condizioni: usare AND/OR con controlli Null espliciti per la logica complessa

Attenzione

Tenere presente che le condizioni che coinvolgono valori Null restituiscono UNKNOWN, che filtra tali righe. Usare controlli espliciti IS NULL quando è necessaria una logica inclusiva null.

ORDER BY istruzione

Sintassi:

ORDER BY <expression> [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ],
         <expression> [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ], ...

Ordinamento a più livelli con espressioni calcolate:

MATCH (p:Person)
RETURN *
ORDER BY p.firstName DESC,               -- Primary: by first name (Z-A)
         p.birthday ASC,                 -- Secondary: by age (oldest first)
         p.id DESC                       -- Tertiary: by ID (highest first)

Gestione dei valori Null nell'ordinamento:

MATCH (p:Person)
RETURN p.firstName, p.birthday
ORDER BY p.birthday DESC NULLS LAST, p.firstName ASC

Dettagli del comportamento di ordinamento:

Informazioni sul funzionamento ORDER BY :

  • Il motore di query valuta le espressioni per ogni riga, quindi i risultati determinano l'ordine di riga.
  • Più chiavi di ordinamento creano un ordinamento gerarchico (primario, secondario, terziario e così via).
  • NULLS FIRST Pone i valori nulli prima dei valori non nulli. NULLS LAST li posiziona dopo valori non nulli.
  • La posizione nulla è indipendente dalla direzione di ordinamento. Se non specifichi l'ordine nullo, NULLS LAST è il valore predefinito sia ASC per che DESCper .
  • ASC (crescente) è l'ordine predefinito ed è necessario specificare DESC in modo esplicito (decrescente).
  • È possibile ordinare in base ai valori calcolati, non solo alle proprietà archiviate.
Specifica di ordinamento Ordine risultante
ASC oppure ASC NULLS LAST Valori non nulli in ordine crescente, seguiti da valori nulli.
ASC NULLS FIRST Valori nulli, seguiti da valori non nulli in ordine crescente.
DESC oppure DESC NULLS LAST Valori non nulli in ordine decrescente, seguiti da valori nulli.
DESC NULLS FIRST Valori nulli, seguiti da valori non nulli in ordine decrescente.

Attenzione

Solo l'istruzione immediatamente seguente può visualizzare l'ordinamento stabilito ORDER BY . Di conseguenza, ORDER BY seguito da RETURN * non produce un risultato ordinato.

Confrontare:

MATCH (a:Person)-[r:knows]->(b:Person)
LET aName = a.firstName || ' ' || a.lastName
LET bName = b.firstName || ' ' || b.lastName
ORDER BY r.creationDate DESC
/* intermediary result _IS_ guaranteed to be ordered here */
RETURN aName, bName, r.creationDate AS since
/* final result _IS_ _NOT_ guaranteed to be ordered here  */

con:

MATCH (a:Person)-[r:knows]->(b:Person)
LET aName = a.firstName || ' ' || a.lastName
LET bName = b.firstName || ' ' || b.lastName
/* intermediary result _IS_ _NOT_ guaranteed to be ordered here */
RETURN aName, bName, r.creationDate AS since
ORDER BY r.creationDate DESC
/* final result _IS_ guaranteed to be ordered here              */

Questa differenza ha conseguenze immediate per le query "Top-k": LIMIT deve sempre seguire l'istruzione che stabilisce l'ordinamento ORDER BY previsto.

OFFSETistruzioni e LIMIT

Sintassi:

  OFFSET <offset> [ LIMIT <limit> ]
| LIMIT <limit>

Modelli comuni:

-- Basic top-N query
MATCH (p:Person)
RETURN *
ORDER BY p.id DESC
LIMIT 10                                 -- Top 10 by ID

Importante

Per risultati di impaginazione prevedibili, usare ORDER BY sempre prima OFFSET e LIMIT per garantire un ordinamento coerente delle righe tra le query.

RETURN: proiezione dei risultati di base

Sintassi:

RETURN [ DISTINCT ] <expression> [ AS <alias> ], <expression> [ AS <alias> ], ...
[ ORDER BY <expression> [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ], ... ]
[ OFFSET <offset> ]
[ LIMIT <limit> ]

L'istruzione RETURN produce l'output finale della query specificando i dati visualizzati nella tabella dei risultati.

Output di base:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName || ' ' || p.lastName AS name, 
       p.birthday, 
       c.name

Uso degli alias per maggiore chiarezza:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName AS first_name, 
       p.lastName AS last_name,
       c.name AS company_name

Combinare con l'ordinamento e top-k:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName || ' ' || p.lastName AS name, 
       p.birthday AS birth_year, 
       c.name AS company
ORDER BY birth_year ASC
LIMIT 10

Duplicare la gestione tramite DISTINCT:

-- Remove duplicate combinations
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN DISTINCT p.gender, p.browserUsed, p.birthday AS birth_year
ORDER BY p.gender, p.browserUsed, birth_year

Combinare con l'aggregazione:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN count(DISTINCT p) AS employee_count

RETURN con GROUP BY: proiezione di risultati raggruppati

Sintassi:

RETURN [ DISTINCT ] <expression> [ AS <alias> ], <expression> [ AS <alias> ], ...
GROUP BY <variable>, <variable>, ...
[ ORDER BY <expression> [ ASC | DESC ], <expression> [ ASC | DESC ], ... ]
[ OFFSET <offset> ]
[ LIMIT <limit> ]

Usare GROUP BY per raggruppare le righe in base ai valori condivisi e alle funzioni di aggregazione di calcolo all'interno di ogni gruppo.

Raggruppamento di base con aggregazione:

MATCH (p:Person)-[:workAt]->(c:Company)
LET companyId = c.id, companyName = c.name
RETURN companyId,
       companyName,
       count(*) AS employeeCount,
       avg(p.birthday) AS avg_birth_year
GROUP BY companyId, companyName
ORDER BY employeeCount DESC

Raggruppamento a più colonne:

MATCH (p:Person)
LET gender = p.gender
LET browser = p.browserUsed
RETURN gender,
       browser,
       count(*) AS person_count,
       avg(p.birthday) AS avg_birth_year,
       min(p.creationDate) AS first_joined,
       max(p.id) AS highest_id
GROUP BY gender, browser
ORDER BY avg_birth_year DESC
LIMIT 10

Annotazioni

Per l'aggregazione orizzontale su pattern di lunghezza variabile, vedi Funzioni aggregate.

Valori e tipi valore

I valori GQL includono valori Booleani, stringa, numerici, temporali, list, nodo, edge, path, null e nulla. I tipi sono nullabili a meno che tu non specifichi NOT NULL. Le proprietà utilizzano un sottoinsieme supportato dell'intero sistema di valori di interrogazione.

RETURN 42 AS integerValue,
       'Alice' AS stringValue,
       TRUE AS booleanValue,
       [1, 2, 3] AS listValue

I confronti con null valutano a UNKNOWN; usano IS NULL e IS NOT NULL per test nulli. Le operazioni numeriche possono applicare conversioni implicite tra tipi numerici compatibili.

Annotazioni

Non ogni tipo di valore GQL è supportato in ogni contesto di Graph. Per le restrizioni attuali di proprietà e di query, vedi Tipi di dati.

Per la sintassi letterale, il comportamento di confronto, le conversioni di tipo e la gerarchia dei tipi, vedi valori GQL e tipi di valore.

Expressions

Le espressioni calcolano, confrontano, aggregano e trasformano i valori. Le forme comuni includono riferimenti a proprietà, operatori aritmetici e logici, predicati, chiamate di funzione, espressioni semplici CASE e sottointerrogy:

MATCH (person:Person)
FILTER person.birthday < 19900101
RETURN person.firstName,
       CASE person.gender
         WHEN 'female' THEN 'F'
         WHEN 'male' THEN 'M'
         ELSE 'Other'
       END AS genderCode

GQL utilizza una logica a tre valori: le espressioni booleane possono valutare fino a TRUE, FALSE, o UNKNOWN. A FILTER mantiene solo le righe per le quali il suo predicato è TRUE.

Aggregare funzioni come COUNT, SUM, AVG, MIN, e MAX riassuntare le righe. Elencare predicati come ALL, ANY, NONE, e SINGLE valutare un predicato per gli elementi della lista. Le sottoquery procedura-form EXISTS verificano se una query annidata restituisce una riga.

Per il comportamento completo di operatori, predicati, aggregati e funzioni, vedi espressioni, predicati e funzioni GQL. Per esempi di filtraggio e raggruppamento orientati al compito, vedi Filtra e aggrega dati di grafo.

Tecniche di query avanzate

In questa sezione vengono illustrati modelli e tecniche sofisticate per la creazione di query di gragrafi complesse ed efficienti. Questi modelli vanno oltre l'utilizzo di istruzioni di base per facilitare la composizione di query analitiche avanzate.

Composizione multistatement complessa

Importante

Graph supporta la composizione di istruzioni lineari di base e completa. Le EXCEPToperazioni , INTERSECT, e OTHERWISE set non sono ancora supportate. Per altre informazioni, vedere l'articolo sulle limitazioni correnti.

Comprendere come comporre query complesse in modo efficiente è fondamentale per l'esecuzione avanzata di query sui gra gragrafi.

UNION e UNION ALL

Usa UNION, UNION DISTINCT, oppure UNION ALL per combinare i risultati di due o più blocchi di query lineari:

<query block>
UNION [ DISTINCT | ALL ]
<query block>
-- Combine results from two separate pattern matches
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName AS name, c.name AS affiliation
UNION DISTINCT
MATCH (p:Person)-[:studyAt]->(u:University)
RETURN p.firstName AS name, u.name AS affiliation

Scoperto UNION è equivalente a UNION DISTINCT; entrambi rimuovono righe duplicate. UNION ALL mantiene tutte le righe, inclusi i duplicati.

Ogni blocco di query deve restituire lo stesso insieme di nomi di colonne. L'ordine delle colonne può variare tra i blocchi e i tipi di dati devono essere compatibili.

NEXT

Usare NEXT per eseguire un'altra fase di query sulla tabella restituita dallo stadio precedente:

<query stage>
RETURN <columns>
NEXT
<query stage>

La seguente query trova i dipendenti e le loro aziende, quindi utilizza i nodi dipendenti restituiti in un'altra corrispondenza di pattern:

MATCH (person:Person)-[:workAt]->(company:Company)
RETURN person, company.name AS companyName
NEXT
MATCH (person)-[:isLocatedIn]->(city:City)
RETURN person.firstName AS employee, companyName, city.name AS city

Solo le colonne restituite dalla fase precedente sono nell'ambito dopo NEXT. Puoi usare più NEXT separatori per costruire una sequenza più lunga di fasi di interrogazione.

Entrambi i livelli possono contenere un'unione di blocchi di interrogazione. Un'unione viene valutata all'interno del suo stadio prima che l'output dello stadio attraversi il NEXT confine. Se A, , e C rappresentano blocchi di interrogazione, A UNION B NEXT C raggruppano come (A UNION B) NEXT C, mentre A NEXT B UNION C raggruppano come A NEXT (B UNION C)B.

Istruzioni condizionali

Utilizzare un'istruzione condizionale per instradare ogni riga in ingresso al primo ramo il cui predicato valuta a TRUE:

WHEN <predicate> THEN <linear query statement or { query statements }>
[ WHEN <predicate> THEN <linear query statement or { query statements }> ... ]
[ ELSE <linear query statement or { query statements }> ]

Per instradare le righe da una fase di query precedente, restituisci le colonne richieste e usa NEXT prima dell'istruzione condizionale:

MATCH (p:Person)
RETURN p.firstName AS name, p.birthday AS birthday
NEXT
WHEN birthday < 19800101u THEN
  RETURN name, 'Before 1980' AS era
WHEN birthday < 20000101u THEN
  RETURN name, '1980-1999' AS era
ELSE
  RETURN name, '2000 or later' AS era

Ogni WHEN predicato deve essere booleano. Il motore di query valuta i predicati in ordine per ogni riga di input. Un predicato che valuta o FALSEUNKNOWN non seleziona il proprio ramo. Dopo che un predicato valuta a TRUE, predicati successivi e corpi di rami non selezionati non vengono valutati. Se nessun predicato valuta e TRUE non ELSEc'è , la riga di input non viene restituita.

Predicati e corpi di ramo possono fare riferimento a colonne della fase precedente. Un branch può essere un'unica affermazione lineare, oppure una procedura annidata racchiusa tra parentesi. Usa una procedura annidata quando un branch necessita di più fasi o istruzioni come CALL:

MATCH (p:Person)
RETURN p, p.firstName AS name
NEXT
WHEN p.gender = 'female' THEN {
  CALL {
    MATCH (p)-[:knows]->(friend:Person)
    RETURN count(*) AS friendCount
  }
  RETURN name, friendCount
}
ELSE
  RETURN name, 0u AS friendCount

Ogni ramo ha il proprio ambito locale. I rami fratelli non vedono le variabili create da un altro ramo, e solo le colonne dell'ultimo RETURN ramo selezionato continuano dopo l'istruzione condizionale. Ogni ramo deve restituire gli stessi nomi di colonna e i tipi di risultato corrispondenti devono essere compatibili. Il motore di query costringe tipi compatibili a un tipo di output comune. Una colonna di ramo restituita può usare lo stesso nome di una colonna in ingresso; il valore del ramo sostituisce il valore in ingresso nell'output condizionale.

Le affermazioni condizionali sono diverse dalle CASE espressioni. Graph supporta espressioni semplici CASE <expression> WHEN <value>, ma non ricercate CASE WHEN <predicate> . Per maggiori informazioni, vedi Espressioni condizionali.

Ambito variabile e controllo del flusso avanzato

Le variabili connettono i dati tra istruzioni di query e abilitano attraversamenti di gragrafi complessi. La comprensione delle regole di ambito avanzate consente di scrivere query sofisticate con più istruzioni.

Binding di variabili e modelli di ambito

-- Variables flow forward through subsequent statements 
MATCH (p:Person)                                    -- Bind p 
LET fullName = p.firstName || ' ' || p.lastName     -- Bind concatenation of p.firstName and p.lastName as fullName
FILTER fullName CONTAINS 'Smith'                    -- Filter for fullNames with “Smith” substring (p is still bound)
RETURN p.id, fullName                               -- Only return p.id and fullName (p is dropped from scope) 

Riutilizzo delle variabili per join tra istruzioni

-- Multi-statement joins using variable reuse
MATCH (p:Person)-[:workAt]->(:Company)          -- Find people with jobs
MATCH (p)-[:isLocatedIn]->(:City)               -- Same p: people with both job and residence
MATCH (p)-[:knows]->(friend:Person)             -- Same p: their social connections
RETURN *

Regole e limitazioni di ambito critiche

-- ✅ Backward references work
MATCH (p:Person)
LET adult = p.birthday < 20061231  -- Can reference p from previous statement
RETURN *

-- ❌ Forward references don't work  
LET adult = p.birthday < 20061231  -- Error: p not yet defined
MATCH (p:Person)
RETURN *

-- ❌ Variables in same LET statement can't reference each other
MATCH (p:Person)
LET name = p.firstName || ' ' || p.lastName,
    greeting = 'Hello, ' || name     -- Error: name not visible yet
RETURN *

-- ✅ Use separate statements for dependent variables
MATCH (p:Person)
LET name = p.firstName || ' ' || p.lastName
LET greeting = 'Hello, ' || name     -- Works: name now available
RETURN *

Visibilità delle variabili nelle query complesse

-- Variables remain visible until overridden or query ends
MATCH (p:Person)                     -- p available from here
LET gender = p.gender                -- gender available from here  
MATCH (p)-[:knows]->(e:Person)       -- p still refers to original person
                                     -- e is a new variable for the friend
RETURN p.firstName AS manager, e.firstName AS friend, gender

Attenzione

Le variabili nella stessa istruzione non possono fare riferimento l'una all'altra, tranne nei modelli a grafo. Usare istruzioni separate per la creazione di variabili dipendenti.

Righe aggregate ed elementi di percorso

GQL supporta due contesti di aggregazione:

  • L'aggregazione verticale riassume le righe di input, opzionalmente suddivise per GROUP BY variabili.
  • L'aggregazione orizzontale riassume una lista di gruppi delimitata da un motivo di spigoli di lunghezza variabile all'interno di un percorso abbinato.
MATCH (person:Person)-[:workAt]->(company:Company)
LET companyId = company.id, companyName = company.name
RETURN companyId, companyName, count(*) AS employeeCount
GROUP BY companyId, companyName
MATCH (:Person)-[connections:knows]->{1,4}(:Person)
RETURN count(connections) AS pathLength

Per query raggruppate, filtri specifici per aggregato, aggregati di raccolta e instradamento condizionale, vedi Filtra e aggrega dati di grafici. Per regole complete dei risultati aggregati, vedi Funzioni aggregate.

Gestire i null ed errori di query

Usa test nulli espliciti quando i valori mancanti richiedono una gestione distinta:

MATCH (person:Person)
FILTER person.browserUsed IS NULL
RETURN person.firstName

Un confronto con null valuta a UNKNOWN, che a FILTER non mantiene. Usalo coalesce() quando hai bisogno di un valore di riserva.

I risultati delle query includono informazioni di stato per successo, avvisi, condizioni di mancanza di dati, errori correggibili dall'utente ed errori di sistema. Usa il codice di stato pubblico per un flusso di controllo ampio e la diagnostica canonica GQLSTATUS per una condizione specifica. Vedi Risultati e risultati di esecuzione e riferimento ai codici di stato GQL.

Parole riservate

GQL riserva determinate parole chiave che non è possibile usare come identificatori come variabili, nomi di proprietà o nomi di etichetta. Per l'elenco completo, vedere le informazioni di riferimento sulle parole riservate GQL .

Se è necessario usare parole riservate come identificatori, eseguirne l'escape con backticks: `match`, `return`.

Per evitare l'escape di parole riservate, usare questa convenzione di denominazione:

  • Per gli identificatori a parola singola, aggiungere un carattere di sottolineatura: :Product_
  • Per gli identificatori di più parole, usare camelCase o PascalCase: :MyEntity, :hasAttribute, textColor

Passaggi successivi