Filtrer et agréger des données de graphique dans Microsoft Fabric

Le filtrage limite vos résultats aux lignes qui importent. L’agrégation récapitule ces lignes en nombres, totaux et moyennes. Cet article explique comment appliquer les deux techniques dans les requêtes GQL sur le graphique dans Microsoft Fabric.

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 pour le filtrage par lignes et motifs, l’agrégation groupée et non groupée, les filtres spécifiques à l’agrégat et le routage conditionnel. Pour construire des motifs multisauts et sélectionner des chemins, voir Écrire des requêtes de motif de graphe. Pour les tâches métier prêtes à s’adapter, voir Écrire des requêtes GQL courantes.

Prerequisites

Filtrer les lignes avec FILTER

Permet FILTER de conserver uniquement les lignes qui répondent à une condition. Placez-les FILTER après MATCH pour affiner les résultats correspondants.

La requête suivante affiche toutes les femmes avec leur nom et leur date de naissance.

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

Combinez plusieurs conditions avec AND et OR. Par exemple, la requête suivante retourne les noms de toutes les femmes nées avant 1990 :

MATCH (p:Person)
FILTER p.gender = 'female' AND p.birthday < 19900101
RETURN p.firstName, p.lastName

Conseil / Astuce

Utilisez une clause « inline » WHERE lorsque la condition définit quel nœud ou quelle arête peut participer à la mise en correspondance. À utiliser FILTER lorsque la condition s’applique à la ligne produite par une instruction antérieure. Le placement des prédicats peut modifier les résultats du chemin le plus court ; voir Place prédicats avant ou après la sélection du chemin.

Filtrer lors de la correspondance de motif

Les clauses en ligne WHERE dans un motif MATCH restreignent les nœuds et les arêtes pouvant correspondre. L’optimiseur de requêtes peut appliquer des prédicats équivalents lors du balayage, donc la syntaxe en ligne n’est pas intrinsèquement plus rapide qu’un fichier séparé FILTER. Choisissez la forme qui exprime la sémantique souhaitée.

Par exemple, pour trouver des personnes nées avant 1994 avec l’entreprise où elles travaillent, limitant les résultats aux entreprises dont le nom commence par « A » :

MATCH (p:Person WHERE p.birthday < 19940101)-[:workAt]->(c:Company WHERE c.name STARTS WITH 'A')
RETURN p.firstName, p.lastName, c.name

Filtrer les propriétés des arêtes de la même façon. Par exemple, pour afficher uniquement les personnes qui ont commencé à travailler dans une entreprise en 2000 ou après :

MATCH (p:Person)-[w:workAt WHERE w.workFrom >= 2000]->(c:Company)
RETURN p.firstName, p.lastName, c.name, w.workFrom

Pour plus d’informations sur le choix entre filtrage en ligne et filtrage post-match, voir Optimiser la performance des requêtes GQL.

Gérer les valeurs Null dans les filtres

GQL utilise une logique à trois valeurs : les prédicats sont évalués à TRUE, FALSEou UNKNOWN. Lorsqu’une valeur de propriété est Null, les comparaisons retournent UNKNOWN. FILTER considère UNKNOWN comme ne correspondant pas, donc la ligne est exclue.

Utilisez IS NULL et IS NOT NULL testez explicitement les valeurs Null :

-- Only include people whose browser is known
MATCH (p:Person)
FILTER p.browserUsed IS NOT NULL
RETURN p.firstName, p.browserUsed

Permet coalesce() de remplacer une valeur par défaut lorsqu’une propriété peut être null :

MATCH (p:Person)
RETURN p.firstName, coalesce(p.browserUsed, 'Unknown browser') AS browser

Avertissement

NULL = NULL est évalué à UNKNOWN, et non TRUE. Utilisez IS NULL toujours pour tester les valeurs Null, et non l’égalité.

Agréger les résultats avec RETURN

Utilisez des fonctions d’agrégation dans RETURN pour synthétiser vos résultats. Graphe prend en charge les fonctions agrégées suivantes : COUNT, SUM, AVG, MIN, MAX, COLLECT_LIST, , COLLECT_ONE, et COLLECT_ELEMENTS.

Par exemple, pour compter toutes les personnes du graphique :

MATCH (p:Person)
RETURN count(*) AS totalPeople

Pour compter des valeurs distinctes telles que le nombre d’entreprises distinctes qui emploient des personnes :

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

Filtre d’entrée pour un agrégat

Ajouter FILTER (WHERE predicate) après un agrégat pour ne filtrer que l’entrée de cet agrégat. Les autres agrégats dans le même RETURN continuent de recevoir toutes les lignes d’entrée.

MATCH (p:Person)
RETURN count(*) AS allPeople,
       count(*) FILTER (WHERE p.birthday < 19900101) AS peopleBornBefore1990

Ajoutez LIMIT dans le filtre d’agrégat pour utiliser au maximum autant de lignes qualificatives. La requête applique le prédicat avant la limite spécifique à l’agrégat.

MATCH (p:Person)
RETURN count(*) FILTER (WHERE p.birthday < 19900101 LIMIT 100) AS sampleCount

Les éléments FILTER et LIMIT, spécifiques à l’agrégat, ne suppriment pas les lignes du reste de la requête. Utilisez une instruction FILTER ou une clause WHERE au niveau de la correspondance lorsque vous souhaitez filtrer le flux de lignes.

Collecter des valeurs

Utilisez COLLECT_LIST pour retourner un élément de liste pour chaque valeur d’entrée, y compris les valeurs nulles. Ajouter DISTINCT pour supprimer les doublons.

MATCH (p:Person)
RETURN collect_list(DISTINCT p.browserUsed) AS browsers

COLLECT_ONE renvoie une valeur d’entrée non nulle. La valeur sélectionnée n’est pas déterministe, donc utilisez-la seulement lorsque toute valeur du groupe est acceptable.

COLLECT_ELEMENTS accepte les entrées à valeurs de liste et concaténe leurs éléments en une seule liste :

MATCH (p:Person)
RETURN collect_elements([p.firstName, p.lastName]) AS names

Sans regroupement de colonnes, une requête agrégée sans lignes d’entrée retourne une liste vide de COLLECT_LIST et COLLECT_ELEMENTS et null de COLLECT_ONE.

Regrouper les résultats avec GROUP BY

Utilisez GROUP BY dans RETURN pour regrouper des lignes par valeurs communes et calculer des agrégats au sein de chaque groupe. Ce regroupement est l’équivalent GQL de SQL GROUP BY.

Par exemple, pour compter les employés par entreprise :

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

Regroupez plusieurs colonnes et calculez plusieurs agrégats à la fois. Par exemple, décomposez le nombre de personnes et la plage d’anniversaires par sexe et navigateur, en retournant les 10 combinaisons les plus courantes :

MATCH (p:Person)
LET gender = p.gender
LET browser = p.browserUsed
RETURN gender,
       browser,
       count(*) AS personCount,
       min(p.birthday) AS earliestBirthday,
       max(p.birthday) AS latestBirthday
GROUP BY gender, browser
ORDER BY personCount DESC
LIMIT 10

Note

Toutes les expressions non agrégées dans RETURN doivent apparaître dans GROUP BY. Les expressions qui ne sont pas incluses GROUP BY doivent utiliser une fonction d’agrégation.

Trier et limiter les résultats agrégés

Utilisez ORDER BY et LIMIT ensemble avec GROUP BY pour trouver les meilleurs résultats N.

Par exemple, pour trouver les cinq premières villes par nombre de résidents :

MATCH (p:Person)-[:isLocatedIn]->(city:City)
LET cityId = city.id, cityName = city.name
RETURN cityId, cityName, count(*) AS residentCount
GROUP BY cityId, cityName
ORDER BY residentCount DESC
LIMIT 5

Important

Place ORDER BY avant LIMIT. LIMIT s’applique toujours au jeu de résultats déjà trié.

Lignes de routage avec instructions conditionnelles

Utilisez une instruction conditionnelle pour router chaque ligne entrante vers la première branche correspondante. L’entrée peut provenir de n’importe quelle étape précédente de la requête, pas seulement d’une agrégation. Par exemple, la requête suivante catégorise les entreprises après avoir calculé leur nombre d’employés :

MATCH (p:Person)-[:workAt]->(c:Company)
LET companyId = c.id, companyName = c.name
RETURN companyId, companyName, count(*) AS employeeCount
GROUP BY companyId, companyName
NEXT
WHEN employeeCount >= 100u THEN
  RETURN companyId, companyName, employeeCount, 'Large' AS category
WHEN employeeCount >= 10u THEN
  RETURN companyId, companyName, employeeCount, 'Medium' AS category
ELSE
  RETURN companyId, companyName, employeeCount, 'Small' AS category

Les branches peuvent exécuter des requêtes complètes et des procédures imbriquées, plutôt que de seulement retourner des expressions. L’exemple suivant envoie trois lignes d’entrée à travers différentes formes de branches. Une branche exécute un MATCH, on combine deux agrégats avec UNION ALL puis agrége leurs résultats, et la branche de secours restitue une constante :

FOR selector IN [1, 2, 3]
RETURN selector
NEXT
WHEN selector = 1 THEN
  MATCH (:Person)-[:knows]->(:Person)
  RETURN count(*) AS total, 'Knows edges' AS category
WHEN selector = 2 THEN {
  MATCH (:Person)-[:workAt]->(:Company)
  RETURN count(*) AS partialCount
  UNION ALL
  MATCH (:Person)-[:studyAt]->(:University)
  RETURN count(*) AS partialCount
  NEXT
  RETURN sum(partialCount) AS total, 'Affiliation edges' AS category
}
ELSE
  RETURN 0u AS total, 'No selected metric' AS category

Le moteur de requête évalue les prédicats dans l’ordre de chaque ligne. Il ne fait fonctionner que la première branche correspondante. Si un prédicat évalue à UNKNOWN, l’évaluation continue avec la branche suivante. Sans un ELSE, les lignes qui ne correspondent pas à une WHEN branche sont omises.

Les énoncés conditionnels sont différents des CASE expressions. Graph prend en charge des expressions simples CASE <expression> WHEN <value> pour la sélection de valeurs basée sur l’égalité. Les expressions recherchées CASE WHEN <predicate> ne sont pas prises en charge. Pour plus d’informations, voir Énoncés conditionnels.