Filtrera och aggregera grafdata i Microsoft Fabric

Filtrering begränsar dina resultat till de rader som är viktiga. Sammansättning sammanfattar dessa rader i antal, summor och medelvärden. Den här artikeln visar hur du använder båda teknikerna i GQL-frågor mot grafer i Microsoft Fabric.

I exemplen används exempeldatauppsättningen för sociala nätverk. För en helhetsförklaring av frågeflöde och satser, se GQL-språkguiden.

Använd denna artikel för rader- och mönsterfiltrering, grupperad och ogrupperad aggregering, aggregatespecifika filter samt villkorlig routning. För att konstruera multihopmönster och välja vägar, se Write graph pattern queries. För färdiganpassade affärsuppgifter, se Skriv vanliga GQL-frågor.

Förutsättningar

Filtrera rader med FILTER

Använd FILTER för att endast behålla de rader som uppfyller ett villkor. Placera FILTER efter MATCH för att begränsa de matchade resultaten.

Följande fråga returnerar alla kvinnor med sitt namn och sin födelsedag:

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

Kombinera flera villkor med AND och OR. Följande fråga returnerar till exempel namnen på alla kvinnor födda före 1990:

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

Tips/Råd

Använd en inline-klausul WHERE när villkoret definierar vilken nod eller kant som kan delta i matchningen. Använd FILTER när villkoret gäller för raden som produceras av ett tidigare påstående. Predikatplacering kan ändra resultat för kortaste vägen; se Placera predikater före eller efter val av väg.

Filtrera vid mönstermatchning

Infogade klausuler WHERE i ett MATCH-mönster begränsar vilka noder och kanter som uppfyller villkoren för matchning. Frågeoptimeraren kan tillämpa motsvarande predikat under skanning, så inline-syntaxen är inte automatiskt snabbare än en separat FILTER. Välj den form som uttrycker den avsedda semantiken.

Till exempel för att hitta personer födda före 1994 tillsammans med företaget där de arbetar, vilket begränsar resultaten till företag vars namn börjar med "A":

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

Filtrera kantegenskaper på samma sätt. Om du till exempel bara vill returnera personer som började arbeta på ett företag år 2000 eller senare:

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

För mer information om att välja mellan inline- och post-match-filtrering, se Optimera GQL-frågeprestanda.

Hantera null-värden i filter

GQL använder logik med tre värden: predikat utvärderas till TRUE, FALSEeller UNKNOWN. När ett egenskapsvärde är null returnerar jämförelser UNKNOWN. FILTER UNKNOWN behandlas som inte matchande, så raden exkluderas.

Använd IS NULL och IS NOT NULL för att testa explicit för null-värden:

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

Använd coalesce() för att ersätta ett standardvärde när en egenskap kan vara null:

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

Caution

NULL = NULL utvärderas till UNKNOWN, inte TRUE. Använd IS NULL alltid för att testa null-värden, inte likhet.

Aggregera resultat med RETURN

Använd aggregeringsfunktioner i RETURN för att sammanfatta dina resultat. Graph stöder följande aggregerade funktioner: COUNT, , , AVG, MIN, COLLECT_LISTMAX, COLLECT_ONE, och COLLECT_ELEMENTSSUM.

Om du till exempel vill räkna alla personer i diagrammet:

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

Så här räknar du distinkta värden, till exempel hur många olika företag som anställer personer:

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

Filterindata för ett aggregat

Lägg till FILTER (WHERE predicate) efter en aggregerad för att filtrera endast den aggregerades indata. Andra aggregat i samma RETURN grupp får fortfarande alla indatarader.

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

Lägg till LIMIT i aggregatfiltret för att använda högst lika många kvalificerande rader. Frågan tillämpar predikatet före den aggregatspecifika gränsen.

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

Aggregatspecifika FILTER och LIMIT tar inte bort rader från resten av frågan. Använd en FILTER sats eller en matchningsnivåklausul WHERE när du vill filtrera radströmmen.

Samla in värden

Använd COLLECT_LIST för att returnera ett listelement för varje indatavärde, inklusive nullvärden. Lägg till DISTINCT för att ta bort dubbletter.

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

COLLECT_ONE returnerar ett icke-noll indatavärde. Det valda värdet är inte deterministiskt, så använd det endast när något värde från gruppen är acceptabelt.

COLLECT_ELEMENTS accepterar listvärda indata och sammanfogar deras element till en lista:

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

Utan att gruppera kolumner returnerar en aggregerad fråga utan inmatningsrader en tom lista från COLLECT_LIST och COLLECT_ELEMENTS och en noll från COLLECT_ONE.

Gruppera resultat med GROUP BY

Använd GROUP BY i RETURN för att gruppera rader efter delade värden och beräkningsaggregeringar i varje grupp. Den här gruppering är GQL-motsvarigheten till SQL GROUP BY.

Om du till exempel vill räkna anställda per företag:

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

Gruppera efter flera kolumner och beräkna flera aggregeringar samtidigt. Du kan till exempel dela upp antalet personer och födelsedagsintervall efter kön och webbläsare och returnera de 10 vanligaste kombinationerna:

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

Alla icke-aggregerade uttryck i RETURN måste visas i GROUP BY. Uttryck som inte finns i GROUP BY måste använda en mängdfunktion.

Sortera och begränsa aggregerade resultat

Använd ORDER BY och LIMIT tillsammans med GROUP BY för att hitta top-N-resultat.

Om du till exempel vill hitta de fem främsta städerna efter antal invånare:

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

Viktigt!

Placera ORDER BY före LIMIT. LIMIT gäller alltid för den redan sorterade resultatuppsättningen.

Routerader med villkorliga satser

Använd en villkorssats för att routa varje inkommande rad till den första matchande grenen. Inmatningen kan komma från vilket föregående frågesteg som helst, inte bara från en aggregering. Till exempel kategoriserar följande fråga företag efter att ha beräknat deras antal anställda:

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

Grenar kan köra kompletta frågesatser och nästlade procedurer, istället för att bara returnera uttryck. Följande exempel skickar tre inmatningsrader genom olika grenformer. En gren kör en MATCH, en kombinerar två aggregat med UNION ALL och aggregerar sedan deras resultat, och fallback-grenen returnerar en konstant:

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

Frågemotorn utvärderar predikaten i ordning för varje rad. Den kör bara den första matchande grenen. Om ett predikat resulterar i UNKNOWN, fortsätter utvärderingen med nästa gren. Utan en ELSE, utelämnas rader som inte matchar en WHEN gren.

Villkorliga satser skiljer sig från CASE uttryck. Graph stöder enkla CASE <expression> WHEN <value> uttryck för likvärdsval baserat på likahet. Sökta CASE WHEN <predicate> uttryck stöds inte. För mer information, se Villkorssatser.