Реализация запросов Data Connect

Firebase Data Connect позволяет создавать коннекторы для ваших экземпляров PostgreSQL, управляемых с помощью Google Cloud SQL. Эти коннекторы представляют собой комбинации запросов и мутаций для использования данных из вашей схемы.

В руководстве по началу работы была представлена ​​схема приложения для написания отзывов о фильмах для PostgreSQL.

В этом руководстве также были описаны как развертываемые, так и нерегламентированные административные операции, включая запросы.

  • Развертываемые запросы — это запросы, которые вы реализуете для вызова из клиентских приложений с помощью определяемых вами конечных точек API. Вы объединяете их в коннектор , развертываемый на сервере. Инструменты Data Connect генерируют клиентские SDK на основе вашего API. Развернутые запросы не защищены политикой IAM, поэтому обязательно защитите их с помощью директивы Data Connect @auth .
  • Для чтения данных выполняются произвольные административные запросы из привилегированных сред. Вы можете создавать и выполнять их в консоли Firebase или в локальных средах разработки с помощью нашего расширения Data Connect для VS Code.

В этом руководстве более подробно рассматриваются развертываемые запросы .

Особенности запросов Data Connect

Data Connect позволяет выполнять базовые запросы всеми способами, которые вы ожидаете от базы данных PostgreSQL.

Однако благодаря расширениям Data Connect для GraphQL вы можете реализовывать сложные запросы для более быстрой и эффективной работы приложений:

  • Используйте ключевые скалярные значения, возвращаемые многими операциями, чтобы упростить повторяющиеся операции над записями.
  • Выполняйте запросы в ходе многоэтапных операций изменения данных для поиска информации, экономя строки кода и количество обращений к серверу.

Используйте сгенерированные поля для построения запросов.

Ваши операции Data Connect будут расширять набор полей, автоматически генерируемых Data Connect на основе типов и связей между типами в вашей схеме. Эти поля генерируются локальными инструментами при каждом редактировании вашей схемы.

С помощью сгенерированных полей можно реализовывать запросы все большей сложности, от извлечения отдельных записей или нескольких записей из одной таблицы до нескольких записей из связанных таблиц.

Предположим, ваша схема содержит тип Movie и связанный с ним тип Actor . Data Connect генерирует поля movie , movies , actors_on_movies и другие.

Запрос с использованием
movie

Поле movie представляет собой отдельную запись в таблице Movie .

Используйте это поле для поиска отдельного фильма по его ключу.

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

Запрос с использованием
movies

Поле movies представляет собой список записей в таблице Movie .

Используйте это поле для запроса нескольких фильмов, например, всех фильмов с заданным годом.

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

Запрос с использованием
поле actors_on_movies

Поле actors_on_movies представляет собой список записей, связывающих таблицы Actor и Movie . Используйте это поле для запроса всех актеров, связанных с данным фильмом.

Используйте это поле для запроса всех актеров, связанных с данным фильмом.

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

Основные элементы запроса

Запросы Data Connect — это запросы GraphQL с расширениями Data Connect. Как и в случае с обычным запросом GraphQL, вы можете определить имя операции и список переменных GraphQL.

Data Connect расширяет возможности запросов GraphQL с помощью настраиваемых директив , таких как @auth .

Таким образом, следующий запрос содержит:

  • Определение типа query
  • Имя операции (запроса) ListMoviesByGenre
  • Единственный аргумент запроса, в данном случае переменная $genre String типа.
  • Одна директива, @auth .
  • Одна область — movies .
query ListMoviesByGenre($genre: String!) @auth(level: PUBLIC) {
  movies(where: { genre: { eq: $genre } }) {
    id
    title
  }
}

Для каждого аргумента запроса требуется объявление типа: встроенного, например, String , или пользовательского, определенного в схеме типа, например, Movie .

В этом руководстве мы рассмотрим сигнатуры все более сложных запросов. В заключение вы познакомитесь с мощными и лаконичными выражениями связей, которые можно использовать для создания развертываемых запросов.

Ключевые скалярные значения в запросах

Но сначала несколько слов о ключевых скалярах.

Data Connect определяет специальный скалярный ключ для представления первичных ключей каждой таблицы, обозначаемый параметром {TableType}_Key. Это JSON-объект со значениями первичных ключей.

Скалярные ключи извлекаются в ответе, возвращаемом большинством автоматически генерируемых полей чтения, или, конечно же, из запросов, в которых вы получили все поля, необходимые для формирования скалярного ключа.

Автоматические запросы, например, запрос на просмотр movie в нашем примере, поддерживают аргумент key, который принимает скалярное значение ключа.

Вы можете передать скалярный ключ в качестве литерала. Но вы также можете определить переменные для передачи скалярных ключей в качестве входных данных.

Запрос

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

Ответ

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

Эти данные можно предоставить в JSON-запросе следующим образом (или в других форматах сериализации):

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

Благодаря пользовательскому синтаксическому анализу скалярных значений, объект Movie_Key также может быть создан с использованием объектного синтаксиса, который может содержать переменные. Это особенно полезно, когда по какой-либо причине необходимо разбить отдельные компоненты на разные переменные.

Пишите простые запросы

Вы можете начать писать запросы для получения отдельных записей из вашей базы данных или для получения списка записей из таблицы с возможностью ограничения и упорядочивания результатов.

Получение отдельных записей

Простейший запрос получает одну запись по ID. Ваш запрос будет использовать автоматически сгенерированное поле movie .

Запрос

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

Ответ

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

Извлечь все записи из таблицы

Для получения подмножества полей из полного списка фильмов из таблицы Movies ваш запрос будет использовать автоматически сгенерированное поле movies , и ваша реализация может выглядеть следующим образом.

Запрос

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

Ответ

{
  "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"
      }
    ]
  }
}
    

Используйте операторы orderBy , limit и offset

Естественно, перечисление всех записей из таблицы имеет ограниченную полезность.

Вы можете упорядочивать результаты и выполнять пагинацию. Эти аргументы принимаются, но не возвращаются в результатах.

В данном случае запрос получает названия 10 фильмов, занимающих первые места в рейтинге.

Запрос

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

Ответ

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

Возможно, вам потребуется получить строки, начиная с определенного смещения, например, фильмы с 11 по 20, отсортированные по рейтингу.

Запрос

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

Ответ

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

Используйте псевдонимы в запросах.

Data Connect поддерживает псевдонимы GraphQL в запросах. С помощью псевдонимов вы переименовываете данные, возвращаемые в результатах запроса. Один запрос Data Connect может применять несколько фильтров или других операций запроса в одном эффективном запросе к серверу, фактически выполняя несколько «подзапросов» одновременно. Чтобы избежать конфликтов имен в возвращаемом наборе данных, вы используете псевдонимы для различения подзапросов.

Вот запрос, в котором выражение использует псевдонимы mostPopular и leastPopular .

Запрос

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

Ответ

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

Используйте фильтры запроса

Запросы Data Connect соответствуют всем распространенным фильтрам SQL и операциям сортировки.

Фильтрация по принципу where с использованием операторов orderBy

Возвращает все соответствующие строки из таблицы (и вложенные ассоциации). Возвращает пустой массив, если ни одна запись не соответствует фильтру.

Запрос

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
  }
}
    

Ответ

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

Фильтрация по проверке на наличие нулевых значений

Проверить наличие null значений можно с помощью оператора isNull .

Запрос

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

Ответ

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

Дополнительные операторы см. в справочнике по типам входных объектов .

Фильтрация по сравнению значений

Для сравнения значений в запросах можно использовать такие операторы, как lt (меньше) и ge (больше или равно).

Запрос

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

Ответ

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

Фильтрация с использованием операторов includes и excludes для полей массива.

Вы можете проверить, содержит ли поле массива указанный элемент.

Следующий пример иллюстрирует оператор includes .

Data Connect поддерживает операторы includesAll , excludes , excludesAll и другие. Ознакомьтесь со всеми такими операторами для целых чисел, строк, дат и других типов данных в разделе _ListFilter справочной документации .

Запрос

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

Ответ

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

Фильтрация с использованием строковых операций и регулярных выражений.

В ваших запросах могут использоваться типичные операции поиска и сравнения строк, включая регулярные выражения. Обратите внимание, что для повышения эффективности вы объединяете здесь несколько операций и уточняете их с помощью псевдонимов.

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}}) {...}
}

Фильтрация с использованием операторов _or , _and , _not

Для более сложной логики используйте _or . Data Connect также поддерживает операторы _and и _not .

Запрос

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
  }
}
    

Ответ

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

Пишите реляционные запросы

Запросы Data Connect могут получать доступ к данным на основе связей между таблицами. Вы можете использовать объектные (один к одному) или массивные (один ко многим) связи, определенные в вашей схеме, для создания вложенных запросов, то есть для получения данных для одного типа вместе с данными из вложенного или связанного типа.

В подобных запросах используется специальный синтаксис Data Connect _on_ и _via в генерируемых полях для чтения.

Не забудьте ознакомиться с примером схемы .

Многие к одному

Теперь рассмотрим запрос, чтобы _on_ синтаксис.

Запрос

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

Ответ

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

Один на один

Запрос типа «один к одному» можно написать, используя синтаксис _on_ .

Запрос

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

Ответ

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

Многие ко многим

Запросы типа «многие ко многим» используют синтаксис _via_ . Запрос типа «многие ко многим» может, например, извлечь информацию об актерах для указанного фильма.

Запрос

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

Ответ

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

Но мы можем написать более сложный запрос, используя псевдонимы, для фильтрации по role , чтобы получить актеров и связанные с ними фильмы в результатах mainActors и supportingActors . Поскольку это связь «многие ко многим», используется синтаксис _via_ .

Запрос

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
    }
  }
}
    

Ответ

{
  "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"
        }
      ]
    }
  }
}
    

Агрегационные запросы

Что такое заполнители и зачем их использовать?

Агрегатные поля позволяют выполнять вычисления над списком результатов. С помощью агрегатных полей можно делать, например:

  • Найдите средний балл отзыва.
  • Узнайте общую стоимость товаров в корзине покупок.
  • Найдите товар с самым высоким или самым низким рейтингом.
  • Подсчитайте количество товаров в вашем магазине.

Агрегирование выполняется на сервере, что дает ряд преимуществ по сравнению с вычислением на стороне клиента:

  • Более высокая производительность приложения (поскольку исключаются вычисления на стороне клиента).
  • Снижение затрат на исходящий трафик данных (поскольку отправляются только агрегированные результаты, а не все входные данные).
  • Повышенная безопасность (поскольку вы можете предоставлять клиентам доступ к агрегированным данным, а не ко всему набору данных).

Пример схемы для агрегатов

В этом разделе мы перейдем к примеру схемы витрины магазина, которая хорошо подходит для объяснения того, как использовать агрегатные функции:

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

Простые агрегаты

_количество для всех полей

Простейшее агрегирующее поле — _count : оно возвращает количество строк, соответствующих вашему запросу. Для каждого поля вашего типа Data Connect генерирует соответствующие агрегирующие поля в зависимости от типа поля.

Запрос

query CountProducts {
  products {
    _count
  }
}

Ответ
one

Например, если в вашей базе данных 5 товаров, результат будет следующим:

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

Все поля имеют поле <field>_count , которое подсчитывает, сколько строк содержат ненулевое значение в этом поле.

Запрос

query CountProductsWithExpirationDate {
  products {
    expirationDate_count
  }
}

Ответ
field_count

Например, если у вас есть 3 товара со сроком годности, результат будет следующим:

{
  "products": [
    {
    "expirationDate_count": 3
    }
  ]
}
_min, _max, _sum и _avg для числовых полей

Числовые поля (int, float, int64) также имеют <field>_min , <field>_max , <field>_sum и <field>_avg .

Запрос

query NumericAggregates {
  products {
  quantityInStock_max
  price_min
  price_avg
  quantityInStock_sum
  }
}

Ответ
_min _max _sum _avg

Например, если у вас есть следующие товары:

  • Товар A: quantityInStock: 10 , price: 2.99
  • Товар B: quantityInStock: 5 , price: 5.99
  • Товар C: quantityInStock: 20 , price: 1.99

В результате получится следующее:

{
  "products": [
    {
    "quantityInStock_max": 20,
    "price_min": 1.99,
    "price_avg": 3.6566666666666666,
    "quantityInStock_sum": 35
    }
  ]
}
_min и _max для дат и временных меток

Поля даты и времени имеют значения <field>_min и <field>_max .

Запрос

query DateAndTimeAggregates {
  products {
  expirationDate_max
  expirationDate_min
  }
}

Ответ
_min _maxdatetime

Например, если у вас следующие сроки действия:

  • Продукт A: 2024-01-01
  • Продукт B: 2024-03-01
  • Продукт C: 2024-02-01

В результате получится следующее:

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

Отчетливый

Аргумент distinct позволяет получить все уникальные значения для поля (или комбинации полей). Например:

Запрос

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

Ответ
distinct

Например, если у вас есть следующие производители:

  • Продукт А: manufacturer: "Acme"
  • Продукт B: manufacturer: "Beta"
  • Продукт C: manufacturer: "Acme"

В результате получится следующее:

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

Вы также можете использовать аргумент distinct для агрегированных полей, чтобы вместо этого агрегировать уникальные значения. Например:

Запрос

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

Ответ
distinctonaggregate

Например, если у вас есть следующие производители:

  • Продукт А: manufacturer: "Acme"
  • Продукт B: manufacturer: "Beta"
  • Продукт C: manufacturer: "Acme"

В результате получится следующее:

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

Сгруппированные агрегаты

Выполнение групповой агрегации осуществляется путем выбора комбинации агрегированных и неагрегированных полей определенного типа. Это группирует все совпадающие строки, имеющие одинаковое значение для неагрегированных полей, и вычисляет агрегированные поля для этой группы. Например:

Запрос

query MostExpensiveProductByManufacturer {
  products {
  manufacturer
  price_max
  }
}

Ответ
groupedaggregates

Например, если у вас есть следующие товары:

  • Товар A: manufacturer: "Acme" , price: 2.99
  • Товар B: manufacturer: "Beta" , price: 5.99
  • Товар C: manufacturer: "Acme" , price: 1.99

В результате получится следующее:

{
  "products": [
    { "manufacturer": "Acme", "price_max": 2.99 },
    { "manufacturer": "Beta", "price_max": 5.99 }
  ]
}
having и where сгруппированные агрегаты

Также можно использовать аргументы having и where , чтобы возвращать только те группы, которые соответствуют заданным критериям.

  • having позволяет фильтровать группы по их агрегированным полям.
  • where фильтровать строки на основе неагрегированных полей.

Запрос

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

Ответ
havingwhere

Например, если у вас есть следующие товары:

  • Товар A: manufacturer: "Acme" , price: 2.99
  • Товар B: manufacturer: "Beta" , price: 5.99
  • Товар C: manufacturer: "Acme" , price: 1.99

В результате получится следующее:

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

Сводные данные по всем таблицам

Агрегированные поля можно использовать совместно с полями, создаваемыми в рамках отношений «один ко многим», для ответа на сложные вопросы о ваших данных. Вот модифицированная схема с отдельной таблицей Manufacturer , которую мы можем использовать в примерах:

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

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

Теперь мы можем использовать агрегированные поля, чтобы, например, узнать, сколько товаров производит производитель:

Запрос

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

Ответ
aggregatesacrosstables

Например, если у вас есть следующие производители:

  • Производитель A: name: "Acme" , products_on_manufacturer: 2
  • Производитель B: name: "Beta" , products_on_manufacturer: 1

В результате получится следующее:

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

Поля перечисления запроса

Вы можете запрашивать данные из полей перечисления в вашей схеме .

Предположим, что наша процедура перечисления реализована следующим образом:

enum AspectRatio {
   ACADEMY
   WIDESCREEN
   ANAMORPHIC
   IMAX
   "No information available on aspect ratio"
   UNAVAILABLE
}

Например, вы можете вывести список всех фильмов, отформатированных в предпочитаемом вами соотношении сторон.

query ListMoviesByAspectRatio($aspectRatio: AspectRatio!) @auth(level: PUBLIC) {
  movies(where:
    {originalAspectRatio: {eq: $aspectRatio}}
) {
    id
    title
    imageUrl
    releaseYear
    genre
    rating
    tags
    description
    otherAspectRatios
  }
}

Фильтрация полей перечисления

Для перечислений доступны стандартные действия фильтрации: eq , ne , ge , gt , lt , le , in nin , а также includes , excludes , includesAll и excludesAll для списков.

order «больше» и «меньше» используют порядок значений перечисления для корректного выполнения. Значения в начале перечисления меньше значений в конце определения перечисления.

Например, следующее условие where вернет все фильмы, у которых ratio меньше, чем заданное соотношение сторон.

  • В первом примере, если $aspectRatio равно IMAX, то будут выбраны фильмы с ratio , совпадающим с ACADEMY, WIDESCREEN и ANAMORPHIC.
  • Во втором примере будут возвращены только фильмы, доступные одновременно в форматах ACADEMY и WIDESCREEN.
  movies(where: {originalAspectRatio: {lt: $aspectRatio}})

  movies(where: {otherAspectRatios: {includesAll: [ACADEMY, WIDESCREEN]}})

Выполняйте агрегационные запросы по полям перечисления.

Для перечислений поддерживается только _count .

Следующий запрос подсчитывает общее количество фильмов с каждым соотношением сторон.

query MovieCountByOriginalAspectRatio @auth(level: PUBLIC) {
  movies {
    _count
    originalAspectRatio
  }
}

Вызов запросов перечисления из клиентского кода

Узнайте, как использовать запросы перечисления от клиентов и как проектировать клиентские вызовы для максимальной гибкости в управлении перечислениями, в руководствах по SDK для iOS , Android , веб-приложений и Flutter .

Пишите сложные запросы: используйте поля query для чтения данных в многоэтапных операциях.

Существует множество ситуаций, когда может потребоваться чтение базы данных во время выполнения операции изменения, чтобы проверить и подтвердить существующие данные перед выполнением, например, вставки или обновления. Такие варианты позволяют избежать повторных обращений к базе данных и, следовательно, снизить затраты.

Data Connect поддерживает эту функциональность. См. раздел "Многоэтапные операции" .

Следующие шаги

Возможно, вас заинтересует: