Implementowanie zapytań Data Connect

Firebase Data Connect umożliwia tworzenie łączników do instancji PostgreSQL zarządzanych za pomocą Google Cloud SQL. Te konektory to kombinacje zapytań i mutacji, które umożliwiają korzystanie z danych ze schematu.

W przewodniku dla początkujących przedstawiliśmy schemat aplikacji do oceniania filmów w PostgreSQL.

W tym przewodniku przedstawiliśmy też operacje administracyjne, które można wdrożyć i wykonywać ad hoc, w tym zapytania.

  • Zapytania do wdrożenia to zapytania, które implementujesz w celu wywoływania z aplikacji klienckich za pomocą zdefiniowanych przez Ciebie punktów końcowych interfejsu API. Łączysz je w łącznik wdrożony na serwerze. Data Connect narzędzie generuje pakiety SDK klienta na podstawie Twojego interfejsu API. Wdrożone zapytania nie są chronione przez zasady IAM, więc pamiętaj, aby zabezpieczyć je za pomocą dyrektywy Data Connect @auth.
  • Zapytania administracyjne ad hoc są uruchamiane w środowiskach z uprawnieniami do odczytywania danych. Możesz je tworzyć i wykonywać w konsoli Firebase lub w lokalnych środowiskach deweloperskich za pomocą naszego rozszerzenia Data Connect VS Code.

W tym przewodniku znajdziesz szczegółowe informacje o zapytaniach, które można wdrożyć.

Funkcje zapytań Data Connect

Data Connect umożliwia wykonywanie podstawowych zapytań na wszystkie sposoby, jakich można oczekiwać w przypadku bazy danych PostgreSQL.

Dzięki rozszerzeniom Data Connect do GraphQL możesz jednak wdrażać zaawansowane zapytania, aby tworzyć szybsze i wydajniejsze aplikacje:

  • Używaj skalarów kluczy zwracanych przez wiele operacji, aby uprościć powtarzające się operacje na rekordach.
  • Wykonywanie zapytań w trakcie wieloetapowych operacji mutacji w celu wyszukiwania danych, co pozwala zaoszczędzić wiersze kodu i podróże do serwera.

Używanie wygenerowanych pól do tworzenia zapytań

Operacje Data Connect rozszerzą zestaw pól automatycznie wygenerowanych Data Connect na podstawie typów i relacji między typami w schemacie. Pola te są generowane przez narzędzia lokalne za każdym razem, gdy edytujesz schemat.

Wygenerowanych pól możesz używać do wdrażania coraz bardziej złożonych zapytań, od pobierania pojedynczych lub wielu rekordów z pojedynczych tabel po pobieranie wielu rekordów z powiązanych tabel.

Załóżmy, że schemat zawiera typ Movie i powiązany z nim typ Actor. Data Connect generuje pola movie, movies, actors_on_movies i inne.

Zapytanie z polem
movie

Pole movie reprezentuje pojedynczy rekord w tabeli Movie.

Użyj tego pola, aby wysłać zapytanie o jeden film na podstawie jego klucza.

query GetMovie($myKey: Movie_Key!) {
  movie(key: $myKey) { title }
}

Zapytanie z polem
movies

Pole movies zawiera listę rekordów w tabeli Movie.

Użyj tego pola, aby wysłać zapytanie dotyczące wielu filmów, np. wszystkich filmów z danego roku.

query GetMovies($myYear: Int!) {
  movies(where: { year: { eq: $myYear } }) { title }
}

Zapytanie z polem
actors_on_movies

Pole actors_on_movies reprezentuje listę rekordów, które łączą tabele ActorMovie. Użyj tego pola, aby wysłać zapytanie o wszystkich aktorów powiązanych z danym filmem.

Użyj tego pola, aby wysłać zapytanie o wszystkich aktorów powiązanych z danym filmem.

  query GetActorsOnMovie($myKey: Movie_Key!) {
    actors_on_movies(where: { movie: { key: { eq: $myKey } } }) {
      actor { name }
    }
  }

Podstawowe elementy zapytania

Zapytania Data Connect to zapytania GraphQL z rozszerzeniami Data Connect. Podobnie jak w przypadku zwykłego zapytania GraphQL możesz zdefiniować nazwę operacji i listę zmiennych GraphQL.

Data Connect rozszerza zapytania GraphQL o niestandardowe dyrektywy, takie jak @auth.

Zapytanie:

  • Definicja typu query
  • Nazwa operacji (zapytania) ListMoviesByGenre
  • Jeden argument zapytania, w tym przypadku zmienna $genre typu String
  • Jedna dyrektywa, @auth.
  • jedno pole movies,
query ListMoviesByGenre($genre: String!) @auth(level: PUBLIC) {
  movies(where: { genre: { eq: $genre } }) {
    id
    title
  }
}

Każdy argument zapytania wymaga deklaracji typu, wbudowanego typu, takiego jak String, lub niestandardowego typu zdefiniowanego w schemacie, takiego jak Movie.

W tym przewodniku przyjrzymy się sygnaturom coraz bardziej złożonych zapytań. Na koniec przedstawimy Ci zwięzłe wyrażenia relacji, których możesz używać do tworzenia zapytań gotowych do wdrożenia.

Kluczowe wartości skalarne w zapytaniach

Najpierw jednak uwaga na temat kluczowych wartości skalarnych.

Data Connect definiuje specjalny skalar klucza, który reprezentuje klucze podstawowe każdej tabeli, identyfikowane przez {TableType}_Key. Jest to obiekt JSON zawierający wartości klucza podstawowego.

Kluczowe wartości skalarne możesz pobierać jako odpowiedź zwracaną przez większość automatycznie generowanych pól odczytu lub oczywiście z zapytań, w których pobrano wszystkie pola potrzebne do utworzenia klucza skalarnego.

Pojedyncze zapytania automatyczne, takie jak movie w naszym przykładzie, obsługują argument klucza, który akceptuje skalar klucza.

Skalar klucza możesz przekazać jako literał. Możesz jednak zdefiniować zmienne, aby przekazywać skalarne klucze dostępu jako dane wejściowe.

Zapytanie

query GetMovie($myKey: Movie_Key!) {
  movie(key: $myKey) { title }
}
    

Odpowiedź

{
  "data": {
    "movie": {
      "title": "Example Movie Title"
    }
  }
}
    

Możesz je podać w żądaniu JSON w ten sposób (lub w innych formatach serializacji):

{
  # 
  "variables": {
    "myKey": {"id": "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"}
  }
}

Dzięki niestandardowej analizie skalarnej obiekt Movie_Key można też utworzyć za pomocą składni obiektu, która może zawierać zmienne. Jest to przydatne głównie wtedy, gdy z jakiegoś powodu chcesz podzielić poszczególne komponenty na różne zmienne.

Tworzenie podstawowych zapytań

Możesz zacząć pisać zapytania, aby pobierać poszczególne rekordy z bazy danych, lub wyświetlać listę rekordów z tabeli z opcją ograniczenia i sortowania wyników.

Pobieranie poszczególnych rekordów

Najprostsze zapytanie pobiera pojedynczy rekord według identyfikatora. Zapytanie będzie używać wygenerowanego automatycznie pola movie.

Zapytanie

query GetMovieById($id: UUID!) @auth(level: PUBLIC) {
  movie(id: $id) {
    id
    title
    imageUrl
    genre
  }
}
    

Odpowiedź

{
  "data": {
    "movie": {
      "id": "some-uuid",
      "title": "Example Movie Title",
      "imageUrl": "https://example.com/movie.jpg",
      "genre": "Action"
    }
  }
}
    

Pobieranie wszystkich rekordów w tabeli

Aby pobrać podzbiór pól z pełnej listy filmów z tabeli Movies, zapytanie będzie korzystać z automatycznie wygenerowanego pola movies, a implementacja może wyglądać tak:

Zapytanie

query ListMovies @auth(level: PUBLIC) {
  movies {
    id
    title
    imageUrl
    genre
  }
}
    

Odpowiedź

{
  "data": {
    "movies": [
      {
        "id": "some-uuid",
        "title": "Example Movie Title",
        "imageUrl": "https://example.com/movie.jpg",
        "genre": "Action"
      },
      {
        "id": "another-uuid",
        "title": "Another Movie Title",
        "imageUrl": "https://example.com/another-movie.jpg",
        "genre": "Comedy"
      }
    ]
  }
}
    

Używanie operatorów orderBy, limitoffset

Wyświetlanie wszystkich rekordów z tabeli ma oczywiście ograniczoną przydatność.

Możesz sortować wyniki i dzielić je na strony. Te argumenty są akceptowane, ale nie są zwracane w wynikach.

W tym przypadku zapytanie zwraca tytuły 10 najwyżej ocenianych filmów.

Zapytanie

query MoviesTop10 {
  movies(orderBy: [{ rating: DESC }], limit: 10) {
    # graphql: list the fields from the results to return
    title
  }
}
    

Odpowiedź

{
  "data": {
    "movies": [
      { "title": "Top Movie 1" },
      { "title": "Top Movie 2" },
      { "title": "Top Movie 3" }
      // ... other 7 movies
    ]
  }
}
    

Możesz mieć przypadek użycia, w którym chcesz pobrać wiersze z przesunięciem, np. filmy od 11 do 20 posortowane według oceny.

Zapytanie

query Movies11to20 {
  movies(orderBy: [{ rating: DESC }], limit: 10, offset: 10) {
    # graphql: list the fields from the results to return
    title
  }
}
    

Odpowiedź

{
  "data": {
    "movies": [
      { "title": "Movie 11" },
      { "title": "Movie 12" },
      { "title": "Movie 13" }
      // ... other 7 movies
    ]
  }
}
    

Używanie aliasów w zapytaniach

Data Connect obsługuje w zapytaniach aliasy GraphQL. Za pomocą aliasów możesz zmieniać nazwy danych zwracanych w wynikach zapytania. Pojedyncze zapytanie Data Connect może stosować wiele filtrów lub innych operacji w ramach jednego wydajnego żądania do serwera, co w praktyce oznacza wysyłanie kilku „podzapytań” jednocześnie. Aby uniknąć kolizji nazw w zwróconym zbiorze danych, użyj aliasów do odróżnienia zapytań podrzędnych.

Oto zapytanie, w którym wyrażenie używa aliasów mostPopularleastPopular.

Zapytanie

query ReviewPopularitySpread($genre: String) {
  mostPopular: review(
    first: {
      where: {genre: {eq: $genre}},
      orderBy: {popularity: DESC}
    }
  ),
  leastPopular: review(
    last: {
      where: {genre: {eq: $genre}},
      orderBy: {popularity: DESC}
    }
  )
}
    

Odpowiedź

{
  "data": {
    "mostPopular": [
      { "popularity": 9 }
    ],
    "leastPopular": [
      { "popularity": 1 }
    ]
  }
}
    

Używanie filtrów zapytań

Data Connect zapytania są mapowane na wszystkie typowe filtry i operacje porządkowania SQL.

Filtrowanie za pomocą operatorów whereorderBy

Zwraca wszystkie dopasowane wiersze z tabeli (i zagnieżdżonych powiązań). Zwraca pustą tablicę, jeśli żaden rekord nie pasuje do filtra.

Zapytanie

query MovieByTopRating($genre: String) {
  mostPopular: movies(
    where: { genre: { eq: $genre } },
    orderBy: { rating: DESC }
  ) {
    # graphql: list the fields from the results to return
    id
    title
    genre
    description
  }
}
    

Odpowiedź

{
  "data": {
    "mostPopular": [
      {
        "id": "some-uuid",
        "title": "Example Movie Title",
        "genre": "Action",
        "description": "A great movie"
      }
    ]
  }
}
    

Filtrowanie przez sprawdzanie wartości null

Wartości null możesz testować za pomocą operatora isNull.

Zapytanie

query ListMoviesWithoutDescription {
  movies(where: { description: { isNull: true }}) {
    id
    title
  }
}
    

Odpowiedź

{
  "data": {
    "movies": [
      {
        "id": "some-uuid",
        "title": "Example Movie Title"
      },
      {
        "id": "another-uuid",
        "title": "Another Movie Title"
      }
    ]
  }
}
    

Więcej operatorów znajdziesz w przewodniku po typach obiektów wejściowych.

Filtrowanie za pomocą porównań wartości

W zapytaniach możesz używać operatorów takich jak lt (mniejsze niż) i ge (większe lub równe), aby porównywać wartości.

Zapytanie

query ListMoviesByRating($minRating: Int!, $maxRating: Int!) {
  movies(where: { rating: { ge: $minRating, lt: $maxRating }}) {
    id
    title
  }
}
    

Odpowiedź

{
  "data": {
    "movies": [
      {
        "id": "some-uuid",
        "title": "Example Movie Title"
      },
      {
        "id": "another-uuid",
        "title": "Another Movie Title"
      }
    ]
  }
}
    

Filtrowanie za pomocą operatorów includesexcludes w przypadku pól tablicowych

Możesz sprawdzić, czy pole tablicy zawiera określony element.

Poniższy przykład ilustruje działanie operatora includes.

Data Connect obsługuje includesAll, excludes, excludesAll i inne. Wszystkie operatory dotyczące liczb całkowitych, ciągów znaków, dat i innych typów danych znajdziesz w _ListFilternagłówkach dokumentacji referencyjnej.

Zapytanie

query ListMoviesByTag($tag: String!) {
  movies(where: { tags: { includes: $tag }}) {
    # graphql: list the fields from the results to return
    id
    title
  }
}
    

Odpowiedź

{
  "data": {
    "movies": [
      {
        "id": "some-uuid",
        "title": "Example Movie Title"
      }
    ]
  }
}
    

Filtrowanie za pomocą operacji na ciągach znaków i wyrażeń regularnych

Zapytania mogą korzystać z typowych operacji wyszukiwania i porównywania ciągów znaków, w tym z wyrażeń regularnych. Uwaga: w celu zwiększenia wydajności łączysz tutaj kilka operacji i rozróżniasz je za pomocą aliasów.

query MoviesTitleSearch($prefix: String, $suffix: String, $contained: String, $regex: String) {
  prefixed: movies(where: {title: {startsWith: $prefix}}) {...}
  suffixed: movies(where: {title: {endsWith: $suffix}}) {...}
  contained: movies(where: {title: {contains: $contained}}) {...}
}

Filtrowanie za pomocą operatorów logicznych _or, _and_not

W przypadku bardziej złożonej logiki użyj elementu _or. Data Connect obsługuje też operatory _and_not.

Zapytanie

query ListMoviesByGenreAndGenre($minRating: Int!, $genre: String) {
  movies(
    where: { _or: [{ rating: { ge: $minRating } }, { genre: { eq: $genre } }] }
  ) {
    # graphql: list the fields from the results to return
    title
  }
}
    

Odpowiedź

{
  "data": {
    "movies": [
      { "title": "Movie Title 1" },
      { "title": "Movie Title 2" }
    ]
  }
}
    

Tworzenie zapytań relacyjnych

Zapytania Data Connect mogą uzyskiwać dostęp do danych na podstawie relacji między tabelami. Możesz używać relacji obiektów (jeden do jednego) lub tablic (jeden do wielu) zdefiniowanych w schemacie do tworzenia zagnieżdżonych zapytań, czyli pobierania danych jednego typu wraz z danymi z zagnieżdżonego lub powiązanego typu.

Takie zapytania używają magicznej składni Data Connect _on__via w wygenerowanych polach odczytu.

Pamiętaj, aby zapoznać się z przykładowym schematem.

Wiele do jednego

Przyjrzyjmy się teraz zapytaniu, aby zilustrować _on_ składnię.

Zapytanie

query MyReviews @auth(level: USER) {
  user(key: {id_expr: "auth.uid"}) {
    reviews: reviews_on_user {
      movie { name }
      rating
    }
  }
}
    

Odpowiedź

{
  "data": {
    "user": {
      "reviews": [
        {
          "movie": { "name": "Movie Title" },
          "rating": 5
        }
      ]
    }
  }
}
    

Jeden do jednego

Możesz napisać zapytanie typu 1:1, używając składni _on_.

Zapytanie

query GetMovieMetadata($id: UUID!) @auth(level: PUBLIC) {
  movie(id: $id) {
    movieMetadatas_on_movie {
      director
    }
  }
}
    

Odpowiedź

{
  "data": {
    "movie": {
      "movieMetadatas_on_movie": {
        "director": "Some Director"
      }
    }
  }
}
    

Wiele do wielu

Zapytania typu „wiele do wielu” korzystają ze składni _via_. Zapytanie typu wiele-do-wielu może pobrać aktorów dla określonego filmu.

Zapytanie

query MoviesActors($id: UUID!) @auth(level: USER) {
  movie(id: $id) {
     actors: actors_via_MovieActors {
        name
     }
  }
}
    

Odpowiedź

{
  "data": {
    "movie": {
      "actors": [
        {
          "name": "Actor Name"
        }
      ]
    }
  }
}
    

Możemy jednak napisać bardziej złożone zapytanie z użyciem aliasów, aby filtrować wyniki na podstawie role i pobrać aktorów i powiązane z nimi filmy w mainActorssupportingActors. Ponieważ jest to relacja wiele-do-wielu, używana jest składnia _via_.

Zapytanie

query GetMovieCast($movieId: UUID!, $actorId: UUID!) @auth(level: PUBLIC) {
  movie(id: $movieId) {
    mainActors: actors_via_MovieActor(where: { role: { eq: "main" } }) {
      name
    }
    supportingActors: actors_via_MovieActor(
      where: { role: { eq: "supporting" } }
    ) {
      name
    }
  }
  actor(id: $actorId) {
    mainRoles: movies_via_MovieActor(where: { role: { eq: "main" } }) {
      title
    }
    supportingRoles: movies_via_MovieActor(
      where: { role: { eq: "supporting" } }
    ) {
      title
    }
  }
}
    

Odpowiedź

{
  "data": {
    "movie": {
      "mainActors": [
        {
          "name": "Main Actor Name"
        }
      ],
      "supportingActors": [
        {
          "name": "Supporting Actor Name"
        }
      ]
    },
    "actor": {
      "mainRoles": [
        {
          "title": "Main Role Movie Title"
        }
      ],
      "supportingRoles": [
        {
          "title": "Supporting Role Movie Title"
        }
      ]
    }
  }
}
    

Zapytania agregujące

Czym są agregaty i dlaczego warto ich używać?

Pola agregacji umożliwiają wykonywanie obliczeń na liście wyników. W przypadku pól zbiorczych możesz na przykład:

  • Znajdowanie średniej oceny
  • Sprawdzanie łącznego kosztu produktów w koszyku
  • Znajdowanie produktu z najwyższą lub najniższą oceną
  • Sprawdź liczbę produktów w sklepie

Agregacje są wykonywane na serwerze, co ma wiele zalet w porównaniu z obliczaniem ich po stronie klienta:

  • szybsze działanie aplikacji (dzięki unikaniu obliczeń po stronie klienta);
  • Niższe koszty przesyłania danych (ponieważ wysyłasz tylko zagregowane wyniki, a nie wszystkie dane wejściowe)
  • większe bezpieczeństwo (ponieważ możesz przyznawać klientom dostęp do zagregowanych danych zamiast do całego zbioru danych);

Przykładowy schemat danych zbiorczych

W tej sekcji przejdziemy do przykładowego schematu sklepu, który dobrze ilustruje, jak używać agregatów:

  type Product @table {
    name: String!
    manufacturer: String!
    quantityInStock: Int!
    price: Float!
    expirationDate: Date
  }

Proste agregacje

_count dla wszystkich pól

Najprostszym polem agregacji jest _count. Zwraca ono liczbę wierszy pasujących do zapytania. W przypadku każdego pola w typie Data Connectgeneruje odpowiednie pola zbiorcze w zależności od typu pola.

Zapytanie

query CountProducts {
  products {
    _count
  }
}

Odpowiedź
one

Jeśli na przykład w bazie danych masz 5 produktów, wynik będzie wyglądać tak:

{
  "products": [
    {
    "_count": 5
    }
  ]
}

Wszystkie pola mają pole <field>_count, które zlicza, ile wierszy ma wartość inną niż null w tym polu.

Zapytanie

query CountProductsWithExpirationDate {
  products {
    expirationDate_count
  }
}

Odpowiedź
field_count

Jeśli na przykład masz 3 produkty z datą ważności, wynik będzie wyglądać tak:

{
  "products": [
    {
    "expirationDate_count": 3
    }
  ]
}
_min, _max, _sum i _avg w przypadku pól liczbowych

Pola numeryczne (int, float, int64) mają też <field>_min, <field>_max,<field>_sum<field>_avg.

Zapytanie

query NumericAggregates {
  products {
  quantityInStock_max
  price_min
  price_avg
  quantityInStock_sum
  }
}

Odpowiedź
_min _max _sum _avg

Załóżmy, że masz te produkty:

  • Produkt A: quantityInStock: 10, price: 2.99
  • Produkt B: quantityInStock: 5, price: 5.99
  • Produkt C: quantityInStock: 20, price: 1.99

Wynik będzie taki:

{
  "products": [
    {
    "quantityInStock_max": 20,
    "price_min": 1.99,
    "price_avg": 3.6566666666666666,
    "quantityInStock_sum": 35
    }
  ]
}
_min i _max w przypadku dat i sygnatur czasowych

Pola daty i sygnatury czasowej mają wartości <field>_min i <field>_max.

Zapytanie

query DateAndTimeAggregates {
  products {
  expirationDate_max
  expirationDate_min
  }
}

Odpowiedź
_min _maxdatetime

Załóżmy, że masz te daty ważności:

  • Produkt A: 2024-01-01
  • Produkt B: 2024-03-01
  • Produkt C: 2024-02-01

Wynik będzie taki:

{
  "products": [
    {
    "expirationDate_max": "2024-03-01",
    "expirationDate_min": "2024-01-01"
    }
  ]
}

Niepowtarzalne

Argument distinct umożliwia uzyskanie wszystkich unikalnych wartości w polu (lub kombinacji pól). Przykład:

Zapytanie

query ListDistinctManufacturers {
  products(distinct: true) {
    manufacturer
  }
}

Odpowiedź
distinct

Załóżmy, że masz tych producentów:

  • Produkt A: manufacturer: "Acme"
  • Produkt B: manufacturer: "Beta"
  • Produkt C: manufacturer: "Acme"

Wynik będzie taki:

{
  "products": [
    { "manufacturer": "Acme" },
    { "manufacturer": "Beta" }
  ]
}

W przypadku pól agregacji możesz też użyć argumentu distinct, aby zamiast tego agregować odrębne wartości. Przykład:

Zapytanie

query CountDistinctManufacturers {
  products {
    manufacturer_count(distinct: true)
  }
}

Odpowiedź
distinctonaggregate

Załóżmy, że masz tych producentów:

  • Produkt A: manufacturer: "Acme"
  • Produkt B: manufacturer: "Beta"
  • Produkt C: manufacturer: "Acme"

Wynik będzie taki:

{
  "products": [
    {
    "manufacturer_count": 2
    }
  ]
}

Agregacje pogrupowane

Agregację grupową możesz przeprowadzić, wybierając kombinację pól agregacji i pól niebędących agregacjami w danym typie. Grupuje ona wszystkie pasujące wiersze, które mają taką samą wartość w polach niezagregowanych, i oblicza pola zagregowane dla tej grupy. Przykład:

Zapytanie

query MostExpensiveProductByManufacturer {
  products {
  manufacturer
  price_max
  }
}

Odpowiedź
groupedaggregates

Załóżmy, że masz te produkty:

  • Produkt A: manufacturer: "Acme", price: 2.99
  • Produkt B: manufacturer: "Beta", price: 5.99
  • Produkt C: manufacturer: "Acme", price: 1.99

Wynik będzie taki:

{
  "products": [
    { "manufacturer": "Acme", "price_max": 2.99 },
    { "manufacturer": "Beta", "price_max": 5.99 }
  ]
}
having i where z pogrupowanymi wartościami zagregowanymi

Możesz też użyć argumentów havingwhere, aby zwracać tylko grupy, które spełniają podane kryteria.

  • having umożliwia filtrowanie grup według pól zbiorczych.
  • where umożliwia filtrowanie wierszy na podstawie pól niezagregowanych.

Zapytanie

query FilteredMostExpensiveProductByManufacturer {
  products(having: {price_max: {ge: 2.99}}) {
  manufacturer
  price_max
  }
}

Odpowiedź
havingwhere

Załóżmy, że masz te produkty:

  • Produkt A: manufacturer: "Acme", price: 2.99
  • Produkt B: manufacturer: "Beta", price: 5.99
  • Produkt C: manufacturer: "Acme", price: 1.99

Wynik będzie taki:

{
  "products": [
    { "manufacturer": "Acme", "price_max": 2.99 },
    { "manufacturer": "Beta", "price_max": 5.99 }
  ]
}

Agregacje w tabelach

Pola agregacji można wykorzystywać w połączeniu z wygenerowanymi polami relacji jeden-do-wielu, aby uzyskiwać odpowiedzi na złożone pytania dotyczące danych. Oto zmodyfikowany schemat z osobną tabelą Manufacturer, której możemy użyć w przykładach:

  type Product @table {
    name: String!
    manufacturer: Manufacturer!
    quantityInStock: Int!
    price: Float!
    expirationDate: Date
  }

  type Manufacturer @table {
    name: String!
    headquartersCountry: String!
  }

Teraz możemy używać pól zbiorczych do wykonywania takich czynności jak sprawdzanie, ile produktów wytwarza dany producent:

Zapytanie

query GetProductCount($id: UUID) {
  manufacturers {
    name
    products_on_manufacturer {
      _count
    }
  }
}

Odpowiedź
aggregatesacrosstables

Załóżmy, że masz tych producentów:

  • Producent A: name: "Acme", products_on_manufacturer: 2
  • Producent B: name: "Beta", products_on_manufacturer: 1

Wynik będzie taki:

{
  "manufacturers": [
    { "name": "Acme", "products_on_manufacturer": { "_count": 2 } },
    { "name": "Beta", "products_on_manufacturer": { "_count": 1 } }
  ]
}

Pisanie zaawansowanych zapytań: używaj pól query do odczytywania danych w operacjach wieloetapowych.

W wielu sytuacjach możesz chcieć odczytać bazę danych podczas wykonywania mutacji, aby wyszukać i zweryfikować istniejące dane przed wykonaniem np. wstawień lub aktualizacji. Te opcje pozwalają zaoszczędzić operacje w obie strony, a tym samym koszty.

Data Connect obsługuje tę funkcję. Zobacz operacje wieloetapowe.

Dalsze kroki

Może Cię zainteresować: