Agregacje w interfejsie API dla języka GraphQL

Przekształć dane usługi Microsoft Fabric w szczegółowe informacje umożliwiające podejmowanie działań za pomocą agregacji GraphQL. Zamiast pobierać tysiące pojedynczych rekordów i przetwarzać je w aplikacji, możesz poprosić sieć szkieletową o zgrupowanie danych i obliczenie podsumowań po stronie serwera — znacznie poprawia wydajność i zmniejsza transfer danych.

Agregacje graphQL działają jak operacje SQL GROUP BY, ale za pośrednictwem interfejsu API GraphQL. Możesz liczyć elementy na kategorię, obliczać sumy przychodów, znajdować średnie oceny lub określać wartości minimalne/maksymalne w tabelach typu lakehouse i warehouse — wszystkie w jednym, wydajnym zapytaniu.

Najważniejsze korzyści:

  • Przetwarzanie po stronie serwera: wykorzystaj zoptymalizowane silniki zapytań Fabric do obliczeń
  • Skrócony transfer danych: pobieranie podsumowań zamiast nieprzetworzonych rekordów
  • Wydajność pojedynczego zapytania: zastępowanie wielu operacji po stronie klienta za pomocą jednej agregacji

W tym przewodniku pokazano, jak tworzyć zapytania agregacji przy użyciu praktycznego przykładu handlu elektronicznego, obejmującego wszystko, od podstawowego grupowania do zaawansowanych funkcji i ważnych ograniczeń.

Kto powinien używać agregacji

Agregacje graphQL są przydatne dla:

  • Deweloperzy aplikacji tworzący niestandardowe pulpity nawigacyjne i aplikacje analityczne, które wymagają podsumowania danych Fabric
  • Inżynierowie danych tworzący interfejsy API danych obsługujące wstępnie obliczone metryki i kluczowe wskaźniki wydajności z lakehouse'ów i magazynów Fabric.
  • Deweloperzy analizy biznesowej tworzący niestandardowe rozwiązania analityczne, które uzupełniają usługę Power BI zagregowanymi danymi Fabric
  • Deweloperzy integracji tworzący aplikacje i przepływy pracy, które wymagają statystyk podsumowania z usługi Fabric
  • Analitycy danych tworzący rozwiązania do samoobsługowej analizy, które wymagają pogrupowanych, zagregowanych wglądów z danych Fabric

Jeśli pobierasz dane w celu wyświetlania wykresów, obliczasz sumy, generujesz raporty lub analizujesz trendy, agregacje mogą znacznie poprawić wydajność aplikacji i zmniejszyć transfer danych.

Typowe pytania biznesowe, na które można odpowiedzieć

Agregacje graphQL doskonale sprawdzają się w odpowiedzi na pytania analityczne dotyczące danych usługi Fabric:

  • Liczenie i grupowanie: "Ile produktów należy do każdej kategorii?" lub "Ile zamówień miesięcznie?"
  • Obliczenia finansowe: "Jaki jest całkowity przychód według regionu?" lub "Średnia wartość zamówienia według segmentu klienta?"
  • Metryki wydajności: "Jaka jest najwyższa i najniższa ocena produktu w każdej kategorii?"
  • Szczegółowe informacje o klientach: "Ilu unikatowych klientów odwiedziło w tym miesiącu?" lub "Które miasta mają najbardziej aktywnych użytkowników?"

Te zapytania są idealne do tworzenia pulpitów nawigacyjnych, generowania raportów i obsługi aplikacji analitycznych, w których potrzebne są podsumowane dane, a nie pojedyncze rekordy.

Wymagania wstępne

Przed użyciem agregacji GraphQL upewnij się, że masz:

  • Obszar roboczy usługi Microsoft Fabric z odpowiednimi uprawnieniami
  • Lakehouse lub magazyn z tabelami zawierającymi dane, które mają zostać zagregowane
  • Interfejs API dla punktu końcowego GraphQL skonfigurowany dla elementów Fabric
  • Podstawowa znajomość składni zapytań GraphQL

Gdzie uruchamiać te zapytania

Szybki start: użyj interfejsu API dla edytora GraphQL w obszarze roboczym usługi Fabric, aby przetestować wszystkie przykłady w tym artykule. Edytor udostępnia eksplorację schematu, walidację zapytań i natychmiastowe wyniki.

W przypadku aplikacji: wysyłanie zapytań jako żądań HTTP POST do punktu końcowego graphQL przy użyciu dowolnej biblioteki klienta GraphQL dla języka programowania.

Do programowania: Narzędzia takie jak GraphQL Playground, Bezsenność lub Postman działają dobrze na potrzeby tworzenia i testowania zapytań.

Uwaga / Notatka

Przykłady w tym artykule są gotowe do kopiowania i uruchamiania po skonfigurowaniu interfejsu API dla punktu końcowego graphQL. Niektóre przykłady są skracane w celu zwięzłości i mogą wymagać dostosowania określonego schematu.

Przykładowy scenariusz: dane handlu elektronicznego w usłudze Fabric

W tym przewodniku użyjemy fikcyjnego zestawu danych handlu elektronicznego przechowywanego w Microsoft Fabric lakehouse lub hurtowni danych. W tym scenariuszu przedstawiono sposób analizowania danych detalicznych przy użyciu agregacji GraphQL.

W tym przykładzie dane produktu należą do kategorii, z których każda Product zawiera pola, takie jak cena i ocena (wartości liczbowe idealne do agregacji) i relacja z Category. Po ujawnieniu tych tabel za pomocą interfejsu API usługi Fabric dla języka GraphQL wygenerowany schemat może wyglądać następująco:

type Category {
  id: ID!
  name: String!
  products: [Product!]!  # one-to-many relationship
}

type Product {
  id: Int!
  name: String!
  price: Float!
  rating: Int!
  category_id: Int!
  category: Category!  # many-to-one relationship
}

type ProductResult { # automatically generated, adding groupBy capabilities
  items: [Product!]!
  endCursor: String
  hasNextPage: Boolean!
  groupBy(fields: [ProductScalarFields!]): [ProductGroupBy!]!
}

type Query {
  products(
    first: Int
    after: String
    filter: ProductFilterInput
    orderBy: ProductOrderByInput
  ): ProductResult!
}

W tym przykładzie products zapytanie może zwrócić normalną listę elementów lub, jeśli groupBy jest używana, zagregowane wyniki. Skoncentrujmy się na używaniu funkcji agregacji i groupBy w tym zapytaniu.

Uwaga / Notatka

Nie można pobrać zarówno normalnych elementów, jak i pogrupowanych wyników w tym samym zapytaniu. Aby uzyskać więcej informacji, zobacz Agregacja i nieprzetworzone elementy wykluczają się wzajemnie.

Dostępne funkcje agregacji

Dokładne dostępne funkcje zależą od implementacji, ale typowe operacje agregacji obejmują:

  • count — liczba rekordów (lub wartości innych niż null pola) w grupie.
  • sum — suma wszystkich wartości w polu liczbowym.
  • avg — średnia (średnia) wartości w polu liczbowym.
  • min — wartość minimalna w polu.
  • max — wartość maksymalna w polu.

W agregacjach GraphQL należy określić nazwę funkcji i pole docelowe, jak pokazano w przykładach count(field: id), sum(field: price)itp. Każda funkcja zwraca obiekt umożliwiający wybranie co najmniej jednego pola, do którego został zastosowany.

Uwaga / Notatka

W interfejsie API usługi Microsoft Fabric dla języka GraphQL operacje agregacji, takie jak count, sum, avgi minmax obecnie działają tylko w polach liczbowych lub ilościowych (liczbach całkowitych, zmiennoprzecinkowych). Nie można ich używać bezpośrednio na polach tekstowych ani na polach dat. Na przykład nie można obliczyć "średniej" pola ciągu. Wsparcie dla wykonywania agregacji na innych typach danych (takich jak łączenie tekstu lub minimalna/maksymalna wartość leksykograficzna) może zostać dodane w przyszłych aktualizacjach do Fabric.

Podstawowe informacje dotyczące zapytań agregacji

Aby przeprowadzić agregację w interfejsie API GraphQL usługi Fabric, należy określić groupBy argument w zapytaniu, aby zdefiniować sposób grupowania danych i żądać pól agregacji (takich jak liczby lub sumy) w wyniku. Silnik GraphQL Fabric efektywnie przetwarza te zapytania względem bazowych tabel typu lakehouse lub warehouse, zwracając listę pogrupowanych rekordów z ich wartościami kluczowymi i obliczonymi agregowanymi metrykami.

Przykład 1: Zlicz produkty w ramach kategorii

Grupujmy produkty według ich kategorii i policzmy liczbę produktów w każdej grupie. Zapytanie może wyglądać następująco:

query {
  products {
   groupBy(fields: [category_id]) 
   {
      fields {
         category_id # grouped key values
      }
      aggregations {
        count(field: id) # count of products in each group (count of "id")
     } 
   }
  }
}

W tym zapytaniu:

  • groupBy(fields: [category_id]) informuje silnik GraphQL sieci szkieletowej, aby grupować produkty według pola category_id.
  • W wyborze wyników żądasz group i agregatu count na polu id. Zliczanie id skutecznie zlicza produkty w tej grupie.

Jak wygląda wynik: Każdy element w odpowiedzi reprezentuje jedną grupę kategorii. Obiekt groupBy zawiera klucz grupowania. W tym zawiera się wartość category_id, a count { id } podaje liczbę produktów w tej kategorii.

{
  "data": {
    "products": {
      "groupBy": [
        {
          "fields": {
            "category_id": 1
          },
          "aggregations": {
            "count": 3
          }
        },
        {
          "fields": {
            "category_id": 2
          },
          "aggregations": {
            "count": 2
          }
        },
        // Sample shortened for brevity
      ]
    }
  }
}

Te dane wyjściowe informują nas, że kategoria 1 ma trzy produkty, kategoria 2 ma 2 itd.

Przykład 2: Suma i średnia

W jednym zapytaniu możemy zażądać wielu metryk agregacji. Załóżmy, że chcemy dla każdej kategorii obliczyć łączną cenę wszystkich produktów oraz średnią ocenę.

query {
  products {
   groupBy(fields: [category_id]) 
   {
      fields {
         category_id
      }
     aggregations {
        count(field: id)   # number of products in the category
        sum(field: price)  # sum of all product prices in the category
        avg(field: rating) # average rating of products in the category
     } 
   }
  }
}

To zapytanie zwróci następujące wyniki:

{
  "data": {
    "products": {
      "groupBy": [
        {
          "fields": {
            "category_id": 1
          },
          "aggregations": {
            "count": 3,
            "sum": 2058.98,
            "avg": 4
          }
        },
        {
          "fields": {
            "category_id": 2
          },
          "aggregations": {
            "count": 2,
            "sum": 109.94,
            "avg": 4
          }
        },
        ...
      ]
    }
  }
}

Każdy obiekt grupy zawiera kategorię i obliczone agregacje, takie jak liczba produktów, suma ich cen i średnie oceny w tej kategorii.

Przykład 3. Grupowanie według wielu pól

Można grupować według więcej niż jednego pola, aby uzyskać grupowanie na wielu poziomach. Jeśli na przykład produkt ma pole rating, możesz pogrupować według category_id i rating, a następnie obliczyć średnią wartość price dla grupy.

query {
  products {
   groupBy(fields: [category_id, rating])
   {
      fields {
         category_id
         rating
      }
     aggregations {
        avg(field: price)
     }
   }
  }
}

Pozwoliłoby to zgrupować produkty według unikatowej kombinacji kategorii i klasyfikacji, jak pokazano poniżej:

 {
    "fields": {
        "category_id": 10,
        "rating": 4
    },
    "aggregations": {
        "avg": 6.99
    }
}

I tak dalej dla każdej pary kategorii klasyfikacji w danych.

Wskazówka

Podczas grupowania według wielu pól sortowanie jawne staje się szczególnie ważne w przypadku przewidywalnych wyników. Zobacz Sortowanie pogrupowanych wyników wymaga jawnego porządkowania.

Przykład 4: Używanie odrębnych

Funkcja agregacji obsługuje odrębny modyfikator do zliczenia lub rozważenia unikatowych wartości. Aby na przykład dowiedzieć się, ile różnych kategorii istnieje w kolekcji produktów, możesz użyć odrębnej liczby:

query {
  products {
   groupBy(fields: [category_id]) 
   {
      fields {
         category_id
      }
     aggregations {
        count(field: id, distinct: true) 
     } 
   }
  }
}

To zapytanie zwraca wynik z liczbą unikatowych produktów dla każdej kategorii. Wynik wygląda następująco:

{
  "data": {
    "products": {
      "groupBy": [
        {
          "fields": {
            "category_id": 1
          },
          "aggregations": {
            "count": 3
          }
        },
        {
          "fields": {
            "category_id": 2
          },
          "aggregations": {
            "count": 2
          }
        },
        ...
      ]
    }
  }
}

Wskazówka

Aby uzyskać więcej wskazówek dotyczących tego, kiedy i jak odpowiednio używać distinct, zobacz Używanie distinct w agregacji.

Przykład 5. Używanie aliasów

Możesz utworzyć aliasy dla agregacji w celu zapewnienia zrozumiałych i łatwych do zrozumienia nazw zagregowanych wyników. Na przykład można nazwać agregację w poprzednim przykładzie, ponieważ distinctProductCategoryCount zlicza odrębne kategorie produktów, aby lepiej zrozumieć wyniki:

query {
  products {
   groupBy(fields: [category_id]) 
   {
      fields {
         category_id
      }
     aggregations {
        distinctProductCategoryCount: count(field: id, distinct: true) 
     } 
   }
  }
}

Wynik jest podobny, ale bardziej zrozumiały dla aliasu niestandardowego:

{
  "data": {
    "products": {
      "groupBy": [
        {
          "fields": {
            "category_id": 1
          },
          "aggregations": {
            "distinctProductCategoryCount": 3
          }
        },
        {
          "fields": {
            "category_id": 2
          },
          "aggregations": {
            "distinctProductCategoryCount": 2
          }
        },
        ...
      ]
    }
  }
}

Przykład 6. Używanie klauzuli having

Istnieje możliwość filtrowania zagregowanych wyników za pomocą klauzuli having . Na przykład można zmodyfikować poprzedni przykład tak, aby zwracał tylko wyniki większe niż dwa:

query {
  products {
   groupBy(fields: [category_id]) 
   {
      fields {
         category_id
      }
     aggregations {
        distinctProductCategoryCount: count(field: id, distinct: true, having:  {
           gt: 2
        }) 
     } 
   }
  }
}

Wynik zwraca pojedynczą wartość z jedyną kategorią z więcej niż dwoma produktami:

{
  "data": {
    "products": {
      "groupBy": [
        {
          "fields": {
            "category_id": 1
          },
          "aggregations": {
            "distinctProductCategoryCount": 3
          }
        }
      ]
    }
  }
}

Ograniczenia i najlepsze rozwiązania

W przypadku używania agregacji w interfejsie API usługi Microsoft Fabric dla języka GraphQL należy wziąć pod uwagę ważne reguły i ograniczenia. Postępując zgodnie z tymi najlepszymi rozwiązaniami i zrozumieniem tych ograniczeń, można tworzyć skuteczne zapytania agregacji GraphQL, które zapewniają zaawansowane szczegółowe informacje, zapewniając przewidywalne wyniki, zwłaszcza podczas pracy z dużymi zestawami danych lub implementując stronicowanie.

Funkcja agregacji jest przydatna w przypadku przypadków użycia raportowania i analizy, ale wymaga starannej struktury zapytań. Zawsze sprawdzaj dokładnie, czy groupBy pola są zgodne z wybranymi polami wyjściowymi, dodaj sortowanie pod kątem przewidywalnej kolejności, szczególnie w przypadku stronicowania, oraz odpowiednio używaj odrębnych i agregujących funkcji dla typów danych.

W poniższych sekcjach opisano trzy kluczowe obszary, które należy zrozumieć: Wzajemnie wyklucza się agregacja i nieprzetworzone elementy. Sortowanie pogrupowane wyniki wymagają jawnego porządkowania i odpowiednio używaj odrębnej agregacji.

Agregacja i nieprzetworzone elementy wykluczają się wzajemnie

Obecnie nie można pobrać zarówno zgrupowanych danych podsumowania, jak i nieprzetworzonej listy elementów w tym samym zapytaniu jednocześnie. Gdy używasz groupBy w zapytaniu, interfejs API przełącza się w tryb agregacji i zwraca tylko pogrupowane wyniki. Ten projekt zapewnia jednoznaczną strukturę odpowiedzi — każde zapytanie działa w trybie agregacji lub trybie elementów listy, ale nigdy oba jednocześnie.

Jak to działa w praktyce:

Zapytanie products(...) zwraca jedną z następujących wartości:

  • Lista poszczególnych produktów (jeśli groupBy nie są używane)
  • Lista pogrupowanych wyników z zagregowanymi danymi (gdy groupBy jest używana)

Zwróć uwagę, że w powyższych przykładowych danych zagregowanych odpowiedź zawiera groupBy oraz pola agregacji, ale brakuje zwykłej listy produktów items.

Co się stanie, jeśli spróbujesz użyć obu następujących elementów:

Jeśli spróbujesz zażądać zarówno normalnych elementów, jak i grup w tym samym zapytaniu, aparat GraphQL zwróci błąd lub nie zezwoli na wybór.

Rozwiązanie tymczasowe :

Jeśli potrzebujesz zarówno danych pierwotnych, jak i zagregowanych danych, uruchom dwa oddzielne zapytania: jedno dla danych pierwotnych i jedno dla zagregowanych danych. Takie podejście zapewnia pełną kontrolę nad zestawami danych i można je zoptymalizować na podstawie określonych wymagań dotyczących buforowania i wydajności.

Sortowanie pogrupowanych wyników wymaga jawnego porządkowania

Zagregowane grupy są zwracane w nieprzewidywalnej kolejności, chyba że określisz jawne sortowanie. Zawsze używaj orderBy argumentów lub sort , aby zapewnić spójne, znaczące wyniki.

Dlaczego jawne porządkowanie ma znaczenie:

  • Nieprzewidywalna kolejność domyślna: grupy bez orderBy, mogą zwracać dowolną kolejność określoną przez bazę danych
  • Wymagania dotyczące stronicowania: Stabilna kolejność sortowania jest niezbędna w przypadku spójnego zachowania stronicowania
  • Środowisko użytkownika: Przewidywalne porządkowanie poprawia interpretację danych i niezawodność aplikacji

Kiedy należy określić kolejność:

  • Brak klucza podstawowego w polach groupBy: jeśli pola grupowania nie zawierają klucza podstawowego, musisz dodać orderBy
  • Klucze grupowania inne niż unikatowe: podczas grupowania według pól, takich jak nazwy kategorii lub daty
  • Scenariusze stronicowania: za każdym razem, gdy planujesz używać opcji limitu/przesunięcia lub stronicowania kursora

Najlepsze rozwiązania:

  • Sortuj według wartości agregowanych (takich jak najpierw najwyższa liczba) dla uzyskania lepszych wyników analitycznych
  • Używanie sortowania alfabetycznego dla grup opartych na kategoriach
  • Łączenie wielu kryteriów sortowania dla złożonych potrzeb dotyczących porządkowania

Odpowiednio używaj odrębnej agregacji

Modyfikator distinct eliminuje zduplikowane wartości przed wykonaniem agregacji, zapewniając dokładne obliczenia, gdy dane zawierają duplikaty.

Typowe przypadki użycia:

  • Unikatowe liczby: count(field: category_id, distinct: true) zlicza liczbę różnych kategorii w każdej grupie
  • Deduplikowane sumy: sum(field: price, distinct: true) dodaje każdą unikatową wartość ceny tylko raz na grupę
  • Scenariusze sprzężenia: Gdy produkty pojawiają się wiele razy z powodu sprzężeń tabeli, distinct gwarantuje, że każdy element jest liczony tylko raz

Kiedy należy używać unikatowych elementów:

  • Dane zawierają wiarygodne duplikaty, które mogłyby wypaczyć obliczenia
  • Pracujesz z połączonymi tabelami, które tworzą zduplikowane wiersze
  • Musisz zliczyć unikatowe wartości, a nie łączne wystąpienia

Zagadnienia dotyczące wydajności:

Odrębne operacje wymagają większego przetwarzania. Używaj tylko wtedy, gdy jest to konieczne, aby uzyskać dokładność danych.