Filtern und Aggregieren von Diagrammdaten in Microsoft Fabric

Durch das Filtern werden die Ergebnisse auf die Zeilen beschränkt, die wichtig sind. Aggregation fasst diese Zeilen in Zählungen, Summen und Mittelwerte zusammen. In diesem Artikel erfahren Sie, wie Sie beide Techniken in GQL-Abfragen auf Graph in Microsoft Fabric anwenden.

In den Beispielen wird das Beispiel-Dataset für soziale Netzwerke verwendet. Für eine vollständige Erklärung des Abfrageflusses und der Anweisungen siehe GQL-Sprachleitfaden.

Verwenden Sie diesen Artikel für Zeilen- und Musterfilterung, gruppierte und ungruppierte Aggregation, aggregatespezifische Filter und bedingtes Routing. Zum Aufbau von Multihop-Mustern und zur Auswahl von Pfaden siehe Write graph pattern queries. Für anpassbare Geschäftsaufgaben siehe Häufige GQL-Abfragen schreiben.

Voraussetzungen

Filtern von Zeilen mit FILTER

Wird verwendet FILTER , um nur die Zeilen beizubehalten, die eine Bedingung erfüllen. Platzieren Sie FILTER nach MATCH, um die übereinstimmenden Ergebnisse einzuschränken.

Die folgende Abfrage gibt alle Frauen mit ihrem Namen und Geburtstag zurück:

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

Kombinieren Sie mehrere Bedingungen mit AND und OR. Die folgende Abfrage gibt beispielsweise die Namen aller Frauen zurück, die vor 1990 geboren wurden:

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

Tip

Verwenden Sie eine Inline-Klausel WHERE , wenn die Bedingung definiert, welcher Knoten oder welche Kante am Match teilnehmen darf. Verwenden Sie FILTER , wenn die Bedingung auf die durch eine frühere Aussage erzeugte Zeile angewendet wird. Die Prädikatenplatzierung kann die Ergebnisse des kürzesten Pfades verändern; siehe Platz-Prädikate vor oder nach der Pfadauswahl.

Filtern während des Musterabgleichs

Inline-Klauseln WHERE innerhalb eines Musters beschränken MATCH , welche Knoten und Kanten für das Match qualifizieren. Der Abfrageoptimierer kann während des Scannens äquivalente Prädikate anwenden, sodass die Inline-Syntax nicht automatisch schneller ist als eine separate FILTER. Wählen Sie die Form, die die beabsichtigte Semantik ausdrückt.

Um beispielsweise Personen zu finden, die vor 1994 geboren wurden, zusammen mit dem Unternehmen, in dem sie arbeiten, die Ergebnisse auf Unternehmen beschränken, deren Name mit "A" beginnt:

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

Filtere die Kanten-Eigenschaften auf die gleiche Weise. Um beispielsweise nur Personen zurückzugeben, die 2000 oder später bei einem Unternehmen ihre Arbeit begonnen haben:

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

Weitere Informationen zur Auswahl zwischen Inline-Filterung und Filterung nach dem Abgleich finden Sie unter Optimieren der GQL-Abfrageleistung.

Behandlung von Nullwerten in Filtern

GQL verwendet dreiwertige Logik: Prädikate werden als TRUE, FALSE oder UNKNOWN bewertet. Wenn ein Eigenschaftswert NULL ist, geben Vergleiche UNKNOWN zurück. FILTER wird als nicht übereinstimmend betrachtet, sodass die Zeile ausgeschlossen wird.

Verwenden Sie IS NULL und IS NOT NULL, um explizit auf Nullwerte zu testen.

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

Verwenden Sie coalesce(), um einen Standardwert heranzuziehen, wenn eine Eigenschaft möglicherweise null sein kann.

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

Vorsicht

NULL = NULL ergibt UNKNOWN, nicht TRUE. Verwenden Sie IS NULL immer, um auf Nullwerte zu testen, nicht auf Gleichheit.

Aggregieren von Ergebnissen mit RETURN

Verwenden Sie Aggregatfunktionen, RETURN um Ihre Ergebnisse zusammenzufassen. Der Graph unterstützt folgende aggregierte Funktionen: COUNT, , , AVG, MIN, COLLECT_LISTMAX, , COLLECT_ONE, und COLLECT_ELEMENTSSUM.

Um beispielsweise alle Personen im Diagramm zu zählen:

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

Um unterschiedliche Werte zu zählen, z. B. wie viele unterschiedliche Unternehmen Mitarbeiter beschäftigen:

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

Filtereingabe für ein Aggregat

Addiere FILTER (WHERE predicate) nach einem Aggregat, um nur die Eingaben dieses Aggregats zu filtern. Andere Aggregate im selben RETURN erhalten weiterhin alle Eingabezeilen.

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

Füge im Aggregatfilter hinzu LIMIT , um höchstens so viele qualifizierende Zeilen zu verwenden. Die Abfrage wendet das Prädikat vor dem aggregatspezifischen Limit an.

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

Aggregatspezifische FILTER und LIMIT entfernen keine Zeilen aus dem Rest der Abfrage. Verwenden Sie eine FILTER Statement- oder Match-Level-Klausel WHERE , wenn Sie den Zeilenstrom filtern möchten.

Sammeln von Werten

Verwenden Sie COLLECT_LIST , um für jeden Eingabewert ein Listenelement zurückzugeben, einschließlich Nullwerte. Hinzufügen DISTINCT , um Duplikate zu entfernen.

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

COLLECT_ONE gibt einen nicht-nullen Eingabewert zurück. Der ausgewählte Wert ist nicht deterministisch, daher sollte man ihn nur verwenden, wenn ein beliebiger Wert aus der Gruppe akzeptabel ist.

COLLECT_ELEMENTS akzeptiert listenwertige Eingaben und verkettet ihre Elemente zu einer Liste:

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

Ohne Gruppierung der Spalten liefert eine aggregierte Abfrage ohne Eingabezeilen eine leere Liste aus COLLECT_LIST und COLLECT_ELEMENTS und null aus COLLECT_ONE.

Gruppieren von Ergebnissen mit GROUP BY

Verwenden Sie GROUP BY in RETURN, um Zeilen nach gemeinsamen Werten zu gruppieren und Aggregate innerhalb jeder Gruppe zu berechnen. Diese Gruppierung ist die GQL-Entsprechung von SQL GROUP BY.

Beispielsweise, um Mitarbeiter pro Unternehmen zu zählen:

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

Gruppieren Sie nach mehreren Spalten, und berechnen Sie mehrere Aggregate gleichzeitig. Brechen Sie beispielsweise die Anzahl der Personen und die Geburtstagsspanne nach Geschlecht und Browser herunter und geben Sie die 10 häufigsten Kombinationen zurück:

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

Alle nicht aggregierten Ausdrücke in RETURN müssen in GROUP BYangezeigt werden. Ausdrücke, die nicht in GROUP BY sind, müssen eine Aggregatfunktion verwenden.

Sortieren und Einschränken aggregierter Ergebnisse

Verwenden Sie ORDER BY, LIMIT und GROUP BY zusammen, um die wichtigsten N-Ergebnisse zu finden.

So finden Sie beispielsweise die fünf wichtigsten Städte nach der Anzahl der Einwohner:

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

Von Bedeutung

ORDER BY vor LIMIT. ** LIMIT wird immer auf die bereits sortierte Ergebnismenge angewendet.

Routen von Zeilen mit bedingten Anweisungen

Verwenden Sie eine Bedingung, um jede eingehende Zeile an die erste zutreffende Verzweigung weiterzuleiten. Die Eingabe kann aus jeder vorangegangenen Abfragephase stammen, nicht nur aus einer Aggregation. Zum Beispiel kategorisiert die folgende Abfrage Unternehmen nach Berechnung ihrer Mitarbeiterzahlen:

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

Zweige können vollständige Abfrageanweisungen und verschachtelte Prozeduren ausführen, anstatt nur Ausdrücke zurückzugeben. Das folgende Beispiel sendet drei Eingabezeilen durch verschiedene Zweigformen. Ein Zweig führt einen MATCHaus, einer kombiniert zwei Aggregate mit UNION ALL und aggregiert dann deren Ergebnisse, und der Fallback-Zweig liefert eine Konstante:

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

Die Abfrage-Engine bewertet die Prädikate für jede Zeile in der richtigen Reihenfolge. Es wird nur die erste passende Verzweigung ausgeführt. Wenn ein Prädikat als UNKNOWN ausgewertet wird, wird die Auswertung mit dem nächsten Zweig fortgesetzt. Ohne ELSE werden Zeilen, die keinem WHEN-Zweig entsprechen, weggelassen.

Bedingungsanweisungen unterscheiden sich von CASE-Ausdrücken. Graph unterstützt einfache CASE <expression> WHEN <value> Ausdrücke für gleichheitsbasierte Wertauswahl. Gesuchte CASE WHEN <predicate> Ausdrücke werden nicht unterstützt. Weitere Informationen finden Sie unter Bedingte Anweisungen.