Écrire des requêtes GQL courantes dans Microsoft Fabric

Cet article fournit des modèles de requête GQL pratiques pour les tâches de graphe courantes dans Microsoft Fabric : recherche de voisins, traversée de connexions multiop, identification des connexions partagées, comptage des relations et recherche d’entités sans connexion.

Les exemples utilisent l’exemple de jeu de données de réseau social. Pour une explication complète du flux de requêtes et des énoncés, consultez le guide du langage GQL. Utilisez cet article lorsque vous connaissez la tâche graphique que vous souhaitez accomplir. Pour une instruction systématique sur la construction de motifs de nœuds, d’arêtes et de chemins, voir Écrire requêtes de motifs graphique. Pour des flux de travail détaillés de filtrage et d’agrégation, voir Filtrer et agréger les données graphiques.

Prerequisites

Rechercher des voisins directs

Retourne tous les nœuds connectés à un nœud de départ par un saut.

Trouvez tout le monde qu’une personne spécifique sait :

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

Trouvez toutes les entreprises qu’une personne a travaillé à :

MATCH (p:Person WHERE p.firstName = 'Alice')-[:workAt]->(c:Company)
RETURN c.name, c.url

Trouver des amis d'amis (multi-sauts)

Utilisez des modèles de longueur variable avec {min,max} pour parcourir plusieurs tronçons.

Trouvez les personnes accessibles en exactement deux knows arêtes à partir d’Alice :

MATCH (alice:Person WHERE alice.firstName = 'Alice')-[:knows]->{2,2}(fof:Person)
RETURN DISTINCT fof.firstName, fof.lastName
LIMIT 100

Trouvez tout le monde accessible en trois degrés :

MATCH (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,3}(dst:Person)
RETURN DISTINCT dst.firstName, dst.lastName
LIMIT 100

Trouvez un chemin le plus court d’Alice à chaque personne accessible en quatre sauts :

MATCH p = ANY SHORTEST
  (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}(dst:Person)
RETURN dst.firstName, dst.lastName, path_length(p) AS hopCount
ORDER BY hopCount, dst.lastName
LIMIT 100

Si plusieurs plus courts chemins atteignent la même personne avec le même nombre de sauts, ANY SHORTEST en retourne un sans départage déterministe.

Les prédicats en ligne restreignent les chemins éligibles à ANY SHORTEST. Les filtres de publication s’appliquent après avoir sélectionné le chemin le plus court. Pour des exemples, voir Place les prédicats avant ou après la sélection du chemin.

Conseil / Astuce

Utilisez une borne supérieure finie pour le coût prévisible de la requête. La traversée illimitée ALL WALK n’est pas prise en charge. D’autres modes de chemin non bornés peuvent encore produire de gros résultats. Consultez les limitations actuelles.

Compter les relations par entité

Utilisez GROUP BY avec count(*) pour compter combien de relations possède chaque entité. Pour des motifs détaillés de regroupement, de filtrage agrégé et de routage conditionnel, voir Filtrer et agréger les données de graphes.

Comptez le nombre d’amis que chaque personne a, ordonnées de la plus à la plus petite :

MATCH (p:Person)-[:knows]->(friend:Person)
LET personId = p.id, name = p.firstName || ' ' || p.lastName
RETURN personId, name, count(*) AS friendCount
GROUP BY personId, name
ORDER BY friendCount DESC
LIMIT 20

Calculez une valeur pour chaque entité

Utilisez une sous-requête corrélée CALL pour calculer une valeur pour chaque ligne d’entrée. Les variables issues de la requête externe sont implicitement disponibles à l’intérieur de la sous-requête.

Calculez le nombre d’amis pour chaque personne :

MATCH (p:Person)
CALL {
  MATCH (p)-[:knows]->(friend:Person)
  RETURN count(*) AS friendCount
}
RETURN p.firstName, p.lastName, friendCount
ORDER BY friendCount DESC

Les variables extérieures restent disponibles après CALL. Parmi les variables créées à l’intérieur de la sous-requête, seules les colonnes retournées deviennent disponibles en dehors de celle-ci. Un élément non groupé count(*) renvoie 0 lorsqu’aucun ami correspondant n’existe, donc cette requête conserve les personnes qui n’ont pas d’amis.

Ordinary CALL supprime une ligne externe lorsque la sous-requête ne retourne aucune ligne et produit une ligne de sortie pour chaque ligne de sous-requête lorsqu’il retourne plusieurs lignes. Utilisez OPTIONAL CALL lorsque vous devez conserver une ligne externe qui n’a pas de ligne correspondante dans la sous-requête.

Rechercher des connexions partagées

La réutilisation d’une variable dans deux parties d’un modèle crée une contrainte implicite « même nœud ». Utilisez cette contrainte pour rechercher des entités connectées via une troisième entité partagée.

Trouvez des paires de personnes qui connaissent tous les deux la même personne :

MATCH (a:Person)-[:knows]->(mutual:Person)<-[:knows]-(b:Person)
WHERE a.id < b.id
RETURN a.firstName, b.firstName, mutual.firstName AS sharedContact
LIMIT 100

Trouvez des paires de personnes qui travaillent dans la même entreprise :

MATCH (c:Company)<-[:workAt]-(a:Person), (c)<-[:workAt]-(b:Person)
WHERE a.id < b.id
RETURN a.firstName, b.firstName, c.name AS company
LIMIT 100

Conseil / Astuce

La WHERE a.id < b.id condition empêche les paires en double (Alice-Bob et Bob-Alice) d’apparaître dans les résultats.

Rechercher des entités sans relations

Utilisez NOT EXISTS pour trouver des nœuds pour lesquels une sous-requête corrélée ne retourne aucune ligne.

Trouvez des personnes qui ne travaillent pas dans une entreprise :

MATCH (p:Person)
WHERE NOT EXISTS {
  MATCH (p)-[:workAt]->(c:Company)
  RETURN c
}
RETURN p.firstName, p.lastName
LIMIT 100

Recherchez des billets sans commentaires :

MATCH (post:Post)
WHERE NOT EXISTS {
  MATCH (comment:Comment)-[:replyOf]->(post)
  RETURN comment
}
RETURN post.id, post.content
LIMIT 100

Rechercher des entités avec de nombreuses connexions

Combinez GROUP BY et FILTER pour identifier les nœuds hautement connectés. Cette méthode est utile pour rechercher des nœuds ou des valeurs hors norme.

Trouvez des personnes avec plus de 10 amis :

MATCH (p:Person)-[:knows]->(friend:Person)
LET personId = p.id, name = p.firstName || ' ' || p.lastName
RETURN personId, name, count(*) AS friendCount
GROUP BY personId, name
FILTER friendCount > 10
ORDER BY friendCount DESC

Note

FILTER après GROUP BY fonctionne comme HAVING dans SQL. Il filtre le résultat agrégé, et non les lignes individuelles.