Cette page explique comment utiliser les chemins de graphe dans Spanner Graph.
Dans les bases de données orientées graphe, le type de données de chemin de graphe représente une séquence de nœuds entrelacés avec des arêtes et montre comment ces nœuds et arêtes sont liés. Pour en savoir plus sur le type de données "chemin", consultez Type de chemin de graphique.
Le langage Spanner Graph (GQL) vous permet de créer des chemins de graphe et d'effectuer des requêtes sur ceux-ci. Les exemples de ce document utilisent le même schéma Spanner Graph que celui présenté sur la page Configurer et interroger Spanner Graph.
Construire un chemin de graphe
Vous pouvez créer un chemin de graphique en créant une variable de chemin dans un modèle de graphique ou avec la fonction PATH
.
Nous vous recommandons de créer un chemin de graphique à l'aide de la variable de chemin d'accès. Le format permettant de créer une variable de chemin d'accès est le suivant :
MATCH p = PATH_PATTERN
Pour en savoir plus, consultez Format de graphique.
Exemple
Dans l'exemple suivant, la requête recherche des schémas de transferts d'argent entre des comptes dans FinGraph
.
GRAPH FinGraph
MATCH p = (src:Account {id: 16})-[t:Transfers]->{2}(dst:Account {id: 7})
RETURN TO_JSON(p) AS full_path;
Résultat
full_path |
---|
[{"identifier": ..., "properties": {"id": 16, ...}, ...}, {"identifier": ..., "properties": {"amount": 300.0, ...}, ...}, ...] |
Le résultat indique que la requête a trouvé le modèle Account -> Transfers -> Account
dans la base de données.
Interroger un chemin de graphique
Vous pouvez utiliser les fonctions spécifiques aux chemins suivantes pour interroger un chemin de graphique. Pour obtenir des informations plus générales sur les requêtes Spanner Graph, consultez Présentation des requêtes.
EDGES
La fonction EDGES
renvoie tous les nœuds d'un chemin de graphique. Pour en savoir plus sur la sémantique, consultez EDGES
.
Exemple
Cette requête trouve un chemin entre deux comptes qui passe par un compte intermédiaire.
Elle renvoie la quantité du deuxième bord Transfers
du chemin, qui peut être comprise entre src
et mid
ou entre mid
et dst
.
GRAPH FinGraph
MATCH p = (src:Account {id: 7})-[t1:Transfers]->{1,3}(mid:Account)-[t2:Transfers]->
{1,3}(dst:Account {id: 16})
LET second_edge = EDGES(p)[1]
RETURN DISTINCT src.id AS src, dst.id AS dst, second_edge.amount AS second_edge_amount;
Résultat
src | dst | second_edge_amount |
---|---|---|
7 | 16 | 300 |
NODES
La fonction NODES
renvoie tous les nœuds d'un chemin de graphique. Pour en savoir plus sur la sémantique, consultez NODES
.
Exemple
Cette requête recherche le chemin du graphique de deux transferts, puis renvoie une liste JSON représentant le chemin.
GRAPH FinGraph
MATCH p = (src:Account)-[t:Transfers]->{2}(dst:Account)
RETURN TO_JSON(NODES(p)) AS nodes;
Résultat
nœuds |
---|
[{"identifier": "...", "properties": {"id": 16}, ...}, {"identifier": "...", "properties": {"id": 20, ...}, ...] |
… |
PATH_FIRST
La fonction PATH_FIRST
trouve le premier nœud d'un chemin de graphique. Pour en savoir plus sur la sémantique, consultez PATH_FIRST
.
Exemple
Cette requête recherche le premier nœud d'un chemin de graphe de deux transferts. Elle renvoie le libellé du nœud Account
et l'alias du compte.
GRAPH FinGraph
MATCH p = -[:Transfers]->{1,3}(dst:Account{id: 7})
RETURN DISTINCT PATH_FIRST(p).id AS can_reach_target;
Résultat
can_reach_target |
---|
7 |
16 |
20 |
PATH_LAST
La fonction PATH_LAST
trouve le dernier nœud d'un chemin de graphique. Pour en savoir plus sur la sémantique, consultez PATH_LAST
.
Exemple
Cette requête recherche le dernier nœud d'un chemin de graphe de deux transferts. Elle renvoie le libellé du nœud Account
et l'alias du compte.
GRAPH FinGraph
MATCH p =(start:Account{id: 7})-[:Transfers]->{1,3}
RETURN DISTINCT PATH_LAST(p).id as can_reach_target;
Résultat
can_reach_target |
---|
7 |
16 |
20 |
PATH_LENGTH
La fonction PATH_LENGTH
permet de trouver le nombre d'arêtes dans un chemin de graphique. Pour en savoir plus sur la sémantique, consultez PATH_LENGTH
.
Exemple
Cette requête recherche le nombre d'arêtes dans un chemin de graphe contenant une à trois correspondances.
GRAPH FinGraph
MATCH p = (src:Account)-[e:Transfers]->{1,3}(dst:Account)
RETURN PATH_LENGTH(p) AS num_transfers, COUNT(*) AS num_paths;
Résultat
num_transfers | num_paths |
---|---|
1 | 5 |
2 | 7 |
3 | 11 |
IS_ACYCLIC
La fonction IS_ACYCLIC
vérifie si un chemin de graphique comporte des nœuds qui se répètent. Elle renvoie TRUE
si une répétition est détectée, sinon elle renvoie FALSE
. Pour en savoir plus sur la sémantique, consultez IS_ACYCLIC
.
Exemple
Cette requête vérifie si ce chemin de graphique comporte des nœuds qui se répètent.
GRAPH FinGraph
MATCH p = (src:Account)-[t:Transfers]->{2}(dst:Account)
RETURN IS_ACYCLIC(p) AS is_acyclic_path,
ARRAY_TRANSFORM(NODES(p), n->n.id) AS account_ids;
Résultat
is_acyclic_path | account_ids |
---|---|
TRUE | 16,20,7 |
TRUE | 20,7,16 |
TRUE | 20,7,16 |
FALSE | 16,20,16 |
TRUE | 7,16,20 |
TRUE | 7,16,20 |
FALSE | 20,16,20 |
IS_TRAIL
La fonction IS_TRAIL
vérifie si un chemin de graphique comporte des arêtes répétées. Elle renvoie TRUE
si une répétition est détectée, sinon elle renvoie FALSE
. Pour en savoir plus sur la sémantique, consultez IS_TRAIL
.
Exemple
Cette requête vérifie si ce chemin de graphique comporte des arêtes répétées.
GRAPH FinGraph
MATCH p = (src:Account)-[t:Transfers]->{3}(dst:Account)
WHERE src.id < dst.id
RETURN IS_TRAIL(p) AS is_trail_path,
ARRAY_TRANSFORM(t, t->t.id) AS transfer_ids
Résultat
is_trail_path | transfer_ids |
---|---|
FALSE | 16,20,16 |
TRUE | 7,16,20 |
TRUE | 7,16,20 |
Modes de chemin
Dans Spanner Graph, le comportement par défaut consiste à renvoyer tous les chemins, y compris ceux comportant des nœuds et des arêtes qui se répètent. Vous pouvez utiliser les modes de chemin d'accès suivants pour inclure ou exclure les chemins d'accès comportant des nœuds et des arêtes qui se répètent. Pour en savoir plus sur la sémantique, consultez la documentation sur le mode Chemin.
WALK
Le mode de chemin WALK
renvoie tous les chemins, y compris ceux avec des nœuds et des arêtes qui se répètent. WALK
est le mode de chemin par défaut.
Exemple
La requête suivante montre comment utiliser le mode de chemin WALK
sur un modèle de chemin quantifié.
Le premier chemin d'accès dans les résultats comporte des arêtes répétées.
GRAPH FinGraph
MATCH p = WALK (src:Account)-[t:Transfers]->{3}(dst:Account)
WHERE src.id < dst.id
RETURN ARRAY_TRANSFORM(t, t->t.id) AS transfer_ids
Résultat
transfer_ids |
---|
16,20,16 |
7,16,20 |
7,16,20 |
ACYCLIC
Le mode de chemin ACYCLIC
filtre les chemins comportant des nœuds répétitifs.
Exemple
La requête suivante montre comment utiliser le mode de chemin ACYCLIC
sur un modèle de chemin quantifié.
Le chemin avec des nœuds src
et dst
égaux est filtré.
GRAPH FinGraph
MATCH p = ACYCLIC (src:Account)-[t:Transfers]->{2}(dst:Account)
RETURN ARRAY_TRANSFORM(NODES(p), n->n.id) AS account_ids
Résultat
account_ids |
---|
16,20,7 |
20,7,16 |
20,7,16 |
7,16,20 |
7,16,20 |
TRAIL
Le mode de chemin TRAIL
filtre les chemins comportant des arêtes répétées.
Exemple
La requête suivante montre comment utiliser le mode de chemin TRAIL
sur un modèle de chemin quantifié.
Les chemins comportant des arêtes répétées sont filtrés.
GRAPH FinGraph
MATCH p = TRAIL (src:Account)-[t:Transfers]->{3}(dst:Account)
WHERE src.id < dst.id
RETURN ARRAY_TRANSFORM(t, t->t.id) AS transfer_ids
Résultat
transfer_ids |
---|
7,16,20 |
7,16,20 |
Préfixe de recherche de chemin
Vous pouvez utiliser un préfixe de recherche de chemin pour limiter un modèle de chemin afin de renvoyer le chemin le plus court à partir de chaque partition de données. Pour en savoir plus sur la sémantique, consultez Préfixe de recherche de chemin d'accès.
ANY SHORTEST
Le préfixe de recherche de chemin d'accès ANY SHORTEST
renvoie le chemin d'accès le plus court (celui avec le moins d'arêtes) qui correspond au modèle de chaque partition de données. Si plusieurs chemins les plus courts existent par partition, la fonction en renvoie un.
Exemple
La requête suivante correspond à n'importe quel chemin entre chaque paire de [a, b]
.
GRAPH FinGraph
MATCH p = ANY SHORTEST (a:Account {is_blocked:true})-[t:Transfers]->{1,4}(b:Account)
LET total_amount = SUM(t.amount)
RETURN a.id AS account1_id, total_amount, b.id AS account2_id;
Résultat
account1_id | total_amount | account2_id |
---|---|---|
16 | 500 | 16 |
16 | 800 | 7 |
16 | 300 | 20 |
Règles de conversion
Pour en savoir plus, consultez les règles de conversion GRAPH_PATH.
Exemple de cas d'utilisation
Dans l'exemple de cas d'utilisation suivant, vous trouverez tous les comptes qui ont été routés vers un à trois comptes, à partir de l'ID de compte 20
.
GRAPH FinGraph
MATCH p = (start:Account {id: 20})-[:Transfers]->{1,3}(dst:Account)
RETURN DISTINCT dst.id AS dst;
Résultat
dst |
---|
7 |
16 |
20 |
Toutefois, une requête qui renvoie à l'ID de compte 20
peut être trop large, car elle commence par l'ID de compte 20
. Pour afficher des résultats plus spécifiques, vous pouvez forcer votre requête à n'afficher que les chemins de graphe acycliques sans aucun nœud répétitif.
Pour ce faire, vous pouvez :
- Utilisez
MATCH p = ACYCLIC <path_pattern>
. - Appliquer un filtre
IS_ACYCLIC(p)
dans votre requête
La requête suivante utilise MATCH p = ACYCLIC PATH_PATTERN
:
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->{1,3}(dst:Account)
RETURN DISTINCT dst.id AS dst;
Résultat
dst |
---|
7 |
16 |
Si vous souhaitez connaître le premier compte par lequel l'argent est transféré, vous pouvez exécuter la requête suivante :
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})(-[:Transfers]->
(nexts:Account)){1,3}(dst:Account)
RETURN dst.id AS dst, ARRAY_AGG(DISTINCT nexts[0].id) AS unique_starts;
Cette requête est inhabituelle, car elle introduit une nouvelle variable dans le chemin quantifié à l'aide de nexts
pour obtenir le résultat. Les variables de chemin vous permettent de simplifier la requête :
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->{1,3}(dst:Account)
RETURN dst.id AS dst, ARRAY_AGG(DISTINCT NODES(p)[OFFSET(1)].id) AS unique_starts;
L'utilisation de NODES(p)
renvoie tous les nœuds du chemin d'accès. Étant donné que le premier compte de nœud est spécifié comme start
, le suivant (au premier décalage) est le premier compte par lequel l'argent est transféré.
Résultat
dst | unique_starts |
---|---|
7 | 16, 7 |
Les chemins sont plus utiles lorsqu'il existe plusieurs chemins quantifiés. Vous pouvez ajouter une contrainte selon laquelle les chemins trouvés à partir de start
doivent passer par l'ID de compte 7
:
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->
{1,3}(mid:Account {id: 7})-[:Transfers]->{1,3}(dst:Account)
RETURN dst.id AS dst,
ARRAY_AGG(DISTINCT NODES(p)[OFFSET(1)].id) AS unique_starts;
Bien que l'instruction MATCH
ait changé, le reste de la requête n'a pas besoin d'être modifié. Sans utiliser de variables de chemin d'accès, il existe des cas où Spanner ne peut pas savoir statiquement quel chemin d'accès quantifié inspecter.
À l'aide d'une variable de chemin d'accès, vous pouvez obtenir la somme de tous les transferts :
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->
{1,3}(mid:Account {id: 7})-[:Transfers]->{1,3}(dst:Account)
LET all_transfers = EDGES(p)
LET transfer_amounts = SUM(all_transfers.amount)
RETURN dst.id AS dst,
ARRAY_AGG(DISTINCT NODES(p)[OFFSET(1)].id) AS participating_neighbor_nodes, transfer_amounts;
Résultat
dst | participating_neighbor_nodes | transfer_amounts |
---|---|---|
16 | 7 | 600 |
16 | 7 | 800 |