Utiliser des chemins

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

Étapes suivantes