Firebase Data Connect, Google Cloud SQL ile yönetilen PostgreSQL örnekleriniz için bağlayıcılar oluşturmanıza olanak tanır. Bu bağlayıcılar, verilerinizi kullanmak için bir şemanın, sorguların ve mutasyonların bir kombinasyonudur.
Başlangıç kılavuzunda, PostgreSQL için bir film yorumu uygulaması şeması tanıtıldı. Bu kılavuzda, PostgreSQL için Data Connect şemalarının nasıl tasarlanacağına daha ayrıntılı bir şekilde değinilmektedir.
Bu kılavuzda, Data Connect sorguları ve mutasyonları şema örnekleriyle eşleştirilir. Data Connect şemaları hakkındaki bir kılavuzda neden sorgular (ve mutasyonlar) ele alınıyor? Diğer GraphQL tabanlı platformlar gibi Firebase Data Connect de sorgu öncelikli bir geliştirme platformudur. Bu nedenle, geliştirici olarak veri modellemenizde müşterilerinizin ihtiyaç duyduğu verileri düşünürsünüz. Bu veriler, projeniz için geliştirdiğiniz veri şemasını büyük ölçüde etkiler.
Bu kılavuzda, yeni bir film yorumları şemasıyla başlanır, ardından bu şemadan türetilen sorgular ve mutasyonlar ele alınır ve son olarak temel Data Connect şemasına eşdeğer bir SQL listesi sağlanır.
Film yorumu uygulamasının şeması
Kullanıcıların film yorumları gönderip görüntülemesine olanak tanıyan bir hizmet oluşturmak istediğinizi varsayalım.
Bu tür bir uygulama için ilk bir şemaya ihtiyacınız vardır. Daha sonra karmaşık ilişkisel sorgular oluşturmak için bu şemayı genişleteceksiniz.
Film tablosu
Filmler şemasında aşağıdaki gibi temel yönergeler bulunur:
@table(name)
ve@col(name)
kullanarak SQL tablo ve sütun adlarını özelleştirebilirsiniz. Belirtilmemişse Data Connect, snake_case adları oluşturur.@col(dataType)
tuşlarına basarak SQL sütun türlerini özelleştirebilirsiniz.@default
, ekleme sırasında SQL sütunu varsayılan değerlerini yapılandırmak için kullanılır.
Daha fazla bilgi için @table
, @col
ve @default
ile ilgili referans dokümanlarına göz atın.
# Movies
type Movie @table(name: "movie", key: "id") {
id: UUID! @col(name: "movie_id") @default(expr: "uuidV4()")
title: String!
releaseYear: Int
genre: String @col(dataType: "varchar(20)")
rating: Int
description: String
}
Anahtar skalerler ve sunucu değerleri
Film yorumu uygulamasına daha ayrıntılı bakmadan önce Data Connect anahtar skalerlerini ve sunucu değerlerini tanıtalım.
Anahtar skalerler, Data Connect'in şemalarınızdaki anahtar alanlardan otomatik olarak derlediği kısa nesne tanımlayıcılardır. Anahtar skalerler verimlilikle ilgilidir ve verilerinizin kimliği ve yapısı hakkındaki bilgileri tek bir çağrıda bulmanızı sağlar. Özellikle yeni kayıtlarda sıralı işlemler yapmak istediğinizde ve yaklaşan işlemlere iletilecek benzersiz bir tanımlayıcıya ihtiyaç duyduğunuzda ve ayrıca daha karmaşık işlemler yapmak için ilişkisel anahtarlara erişmek istediğinizde kullanışlıdır.
Sunucu değerlerini kullanarak, expr
bağımsız değişkenindeki belirli sunucu tarafı CEL ifadelerine göre depolanan veya kolayca hesaplanabilen değerleri kullanarak sunucunun tablolarınızdaki alanları dinamik olarak doldurmasına izin verebilirsiniz. Örneğin, bir işlem isteğinde (updatedAt: Timestamp! @default(expr: "request.time")
) depolanan saat kullanılarak alana erişildiğinde zaman damgası uygulanmış bir alan tanımlayabilirsiniz.
Film meta verileri tablosu
Şimdi film yönetmenlerini takip edip Movie
ile bire bir ilişki oluşturalım.
İlişki tanımlamak için referans alanını ekleyin.
Yabancı anahtar kısıtlamasını özelleştirmek için @ref
yönergesini kullanabilirsiniz.
@ref(fields)
kullanarak yabancı anahtar alanlarını belirtin.@ref(references)
kullanarak hedef tabloda referans verilen alanları belirtin. Bu referans varsayılan olarak birincil anahtarı kullanır ancak@unique
içeren alanlar da desteklenir.
Daha fazla bilgi için @ref
ile ilgili referans dokümanlarına göz atın.
# Movie Metadata
# Movie - MovieMetadata is a one-to-one relationship
type MovieMetadata @table {
# @unique ensures that each Movie only has one MovieMetadata.
movie: Movie! @unique
# Since it references to another table type, it adds a foreign key constraint.
# movie: Movie! @unique @ref(fields: "movieId", references: "id")
# movieId: UUID! <- implicitly added foreign key field
director: String
}
Actor ve MovieActor
Ardından, filmlerinizde rol alacak aktörler istiyorsunuz. Filmler ile aktörler arasında çoklu ilişki olduğundan bir birleştirme tablosu oluşturun.
# Actors
# Suppose an actor can participate in multiple movies and movies can have multiple actors
# Movie - Actors (or vice versa) is a many to many relationship
type Actor @table {
id: UUID! @default(expr: "uuidV4()")
name: String! @col(dataType: "varchar(30)")
}
# Join table for many-to-many relationship for movies and actors
# The 'key' param signifies the primary keys of this table
# In this case, the keys are [movieId, actorId], the foreign key fields of the reference fields [movie, actor]
type MovieActor @table(key: ["movie", "actor"]) {
movie: Movie!
# movieId: UUID! <- implicitly added foreign key field
actor: Actor!
# actorId: UUID! <- implicitly added foreign key field
role: String! # "main" or "supporting"
# optional other fields
}
Kullanıcı
Son olarak, uygulamanızın kullanıcıları.
# Users
# Suppose a user can leave reviews for movies
type User @table {
id: String! @default(expr: "auth.uid")
username: String! @col(dataType: "varchar(50)")
}
Desteklenen veri türleri
Data Connect, @col(dataType:)
kullanılarak PostgreSQL türlerine atamalarla aşağıdaki skaler veri türlerini destekler.
Data Connect türü | GraphQL yerleşik türü veya Data Connect özel türü |
Varsayılan PostgreSQL türü | Desteklenen PostgreSQL türleri (parantez içinde takma ad) |
---|---|---|---|
Dize | GraphQL | metin | text bit(n), varbit(n) char(n), varchar(n) |
Int | GraphQL | int | Int2 (smallint, smallserial), int4 (integer, int, serial) |
Kayan | GraphQL | float8 | float4 (reel) float8 (çift hassasiyet) numeric (ondalık) |
Boole | GraphQL | boolean | boolean |
UUID | Özel | uuid | uuid |
Int64 | Özel | bigint | int8 (bigint, bigserial) numeric (ondalık) |
Tarih | Özel | tarih | tarih |
Zaman damgası | Özel | timestamptz | timestamptz Not: Yerel saat dilimi bilgileri depolanmaz. |
Vector | Özel | vector | vektör Vertex AI ile vektör benzerliği araması yapma başlıklı makaleyi inceleyin. |
- GraphQL
List
, tek boyutlu bir diziyle eşlenir.- Örneğin,
[Int]
int5[]
ile,[Any]
isejsonb[]
ile eşlenir. - Data Connect iç içe dizileri desteklemez.
- Örneğin,
Sorgu ve mutasyon oluşturmak için oluşturulan alanları kullanma
Data Connect sorgularınız ve mutasyonlarınız, şemanızdaki türlere ve tür ilişkilerine göre otomatik olarak oluşturulan bir Data Connect alan grubunu genişletir. Bu alanlar, şemanızı her düzenlediğinizde yerel araçlar tarafından oluşturulur.
Başlangıç kılavuzunda da belirtildiği gibi, Firebase konsolu ve yerel geliştirme araçlarımız, bu otomatik olarak oluşturulan alanları kullanarak size veri eklemek ve tablolarınızın içeriğini doğrulamak için kullanabileceğiniz ad hoc yönetimsel sorgular ve mutasyonlar sağlar.
Geliştirme sürecinizde, bu otomatik olarak oluşturulan alanlara göre bağlayıcılarınızda gruplandırılmış dağıtılabilir sorgular ve dağıtılabilir mutasyonlar uygularsınız.
Otomatik olarak oluşturulan alan adlandırma
Data Connect, şema türü beyanlarınıza göre otomatik olarak oluşturulan alanlar için uygun adları çıkarır. Örneğin, PostgreSQL kaynağıyla çalışırken Movie
adlı bir tablo tanımlarsanız sunucu şunları oluşturur:
- Tek tablolu kullanım alanlarında verileri okumak için
movie
(eq
gibi bağımsız değişkenler göndererek tek tek sonuçları almak için tekil) vemovies
(gt
gibi bağımsız değişkenler veorderby
gibi işlemler göndererek sonuç listelerini almak için çoğul) gibi kullanıcı dostu adlara sahip alanlar. Data Connect,actors_on_movies
veyaactors_via_actormovie
gibi açık adlara sahip çok tablolu, ilişkisel işlemler için de alanlar oluşturur. movie_insert
,movie_upsert
gibi bilinen bir ada sahip verileri yazmak için alanlar
Şema tanımı dili, singular
ve plural
yönerge bağımsız değişkenlerini kullanarak alanlar için adların nasıl oluşturulacağını açıkça kontrol etmenize de olanak tanır.
Sorgular ve mutasyonlar için talimatlar
Data Connect, türleri ve tabloları tanımlarken kullandığınız yönergelere ek olarak sorguların ve mutasyonların davranışını geliştirmek için @auth
, @check
, @redact
ve @transaction
yönergelerini sağlar.
Direktif | Geçerlilik kapsamı | Açıklama |
---|---|---|
@auth |
Sorgular ve mutasyonlar | Sorgu veya mutasyon için kimlik doğrulama politikasını tanımlar. Yetkilendirme ve doğrulama kılavuzuna bakın. |
@check |
Yetkilendirme verisi arama sorguları | Belirtilen alanların sorgu sonuçlarında bulunduğunu doğrular. Alan değerlerini test etmek için Common Expression Language (CEL) ifadesi kullanılır. Yetkilendirme ve doğrulama kılavuzuna bakın. |
@redact |
Sorgular | İstemciden gelen yanıtın bir bölümünü çıkartır. Yetkilendirme ve doğrulama kılavuzuna bakın. |
@transaction |
Değişiklikler | Bir mutasyonun her zaman bir veritabanı işleminde çalıştırılmasını zorunlu kılar. Film uygulaması mutasyon örneklerine bakın. |
Film yorumu veritabanı için sorgular
Sorgu işlemi türü beyanı, işlem adı, sıfır veya daha fazla işlem bağımsız değişkeni ve bağımsız değişken içeren sıfır veya daha fazla yönergeyle bir Data Connect sorgusu tanımlarsınız.
Hızlı başlangıç kılavuzundaki örnek listEmails
sorgusunda parametre yoktu. Elbette, sorgu alanlarına iletilen veriler çoğu durumda dinamik olacaktır. Sorgu tanımının bileşenlerinden biri olarak değişkenlerle çalışmak için $variableName
söz dizimini kullanabilirsiniz.
Dolayısıyla aşağıdaki sorguda:
query
türü tanımıListMoviesByGenre
işlemi (sorgu) adı- Tek değişkenli
$genre
işlem bağımsız değişkeni - Tek bir yönerge (
@auth
).
query ListMoviesByGenre($genre: String!) @auth(level: USER)
Her sorgu bağımsız değişkeni için bir tür beyanı, String
gibi yerleşik bir tür veya Movie
gibi şemada tanımlanmış özel bir tür gerekir.
Giderek daha karmaşık hale gelen sorguların imzasını inceleyelim. Dersi, dağıtılabilir sorgularınızı oluşturmak için kullanabileceğiniz güçlü ve kısa ilişki ifadelerini tanıtarak sonlandıracaksınız.
Sorgulardaki temel skalerler
Ancak öncelikle, temel skalerlerle ilgili bir not.
Data Connect, _Key
ile tanımlanan anahtar skalerler için özel bir tür tanımlar. Örneğin, Movie
tablomuzdaki bir anahtar skalerinin türü Movie_Key
'dur.
Anahtar skalerleri, otomatik olarak oluşturulan çoğu okuma alanı tarafından döndürülen bir yanıt olarak veya elbette skaler anahtarı oluşturmak için gereken tüm alanları aldığınız sorgulardan alırsınız.
Çalışan örneğimizdeki movie
gibi tekil otomatik sorgular, bir anahtar skaler kabul eden bir anahtar bağımsız değişkenini destekler.
Bir anahtar skalerini değişmez değer olarak iletebilirsiniz. Ancak, giriş olarak temel skaler göndermek için değişkenler tanımlayabilirsiniz.
query GetMovie($myKey: Movie_Key!) {
movie(key: $myKey) { title }
}
Bunlar, istek JSON'unda aşağıdaki gibi (veya diğer serileştirme biçimlerinde) sağlanabilir:
{
# …
"variables": {
"myKey": {"foo": "some-string-value", "bar": 42}
}
}
Özel skaler ayrıştırma sayesinde, Movie_Key
değişken içerebilen nesne söz dizimi kullanılarak da oluşturulabilir. Bu yöntem, genellikle bir nedenle tek tek bileşenleri farklı değişkenlere bölmek istediğinizde yararlıdır.
Sorgularda takma ad kullanma
Data Connect, sorgularda GraphQL takma adlandırmasını destekler. Takma adlar sayesinde, bir sorgunun sonuçlarında döndürülen verileri yeniden adlandırabilirsiniz. Tek bir Data Connect sorgusu, sunucuya tek bir verimli istek göndererek birden fazla filtre veya başka sorgu işlemleri uygulayabilir ve aynı anda birkaç "alt sorgu" yayınlayabilir. Döndürülen veri kümesinde ad çakışmalarını önlemek için alt sorguları ayırt etmek üzere takma adlar kullanırsınız.
Aşağıda, bir ifadenin mostPopular
takma adını kullandığı bir sorgu verilmiştir.
query ReviewTopPopularity($genre: String) {
mostPopular: review(first: {
where: {genre: {eq: $genre}},
orderBy: {popularity: DESC}
}) { … }
}
Filtre içeren basit sorgular
Data Connect sorguları, tüm yaygın SQL filtreleriyle ve sıralama işlemleriyle eşlenir.
where
ve orderBy
operatörleri (tekil, çoğul sorgular)
Tablodaki eşleşen tüm satırları (ve iç içe geçmiş ilişkilendirmeleri) döndürür. Filtreyle eşleşen bir kayıt yoksa boş bir dizi döndürür.
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
}
}
query MoviesByReleaseYear($min: Int, $max: Int) {
movies(where: {releaseYear: {le: $max, ge: $min}}, orderBy: [{releaseYear: ASC}]) { … }
}
limit
ve offset
operatörleri (tekil, çoğul sorgular)
Sonuçlarda sayfalandırma yapabilirsiniz. Bu bağımsız değişkenler kabul edilir ancak sonuçlarda döndürülmez.
query MoviesTop10 {
movies(orderBy: [{ rating: DESC }], limit: 10) {
# graphql: list the fields from the results to return
title
}
}
Dizi alanları için içerir
Bir dizi alanının belirtilen bir öğeyi içerip içermediğini test edebilirsiniz.
# Filter using arrays and embedded fields.
query ListMoviesByTag($tag: String!) {
movies(where: { tags: { includes: $tag }}) {
# graphql: list the fields from the results to return
id
title
}
}
Dize işlemleri ve normal ifadeler
Sorgularınızda normal ifadeler de dahil olmak üzere normal dize arama ve karşılaştırma işlemleri kullanılabilir. Verimliliği artırmak için burada birkaç işlemi bir araya getirdiğinizi ve bunları takma adlarla açıklığa kavuşturduğunuzu unutmayın.
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}}) {...}
matchRegex: movies(where: {title: {pattern: {regex: $regex}}}) {...}
}
Birleştirilmiş filtreler için or
ve and
Daha karmaşık mantık için or
ve and
kullanın.
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
}
}
Karmaşık sorgular
Data Connect sorguları, tablolar arasındaki ilişkilere göre verilere erişebilir. İç içe yerleştirilmiş sorgular oluşturmak (ör. iç içe yerleştirilmiş veya ilgili bir türden veri ile birlikte bir tür için veri almak) amacıyla şemanızda tanımlanan nesne (bire bir) veya dizi (bir çok) ilişkilerini kullanabilirsiniz.
Bu tür sorgular, oluşturulan okuma alanlarında sihirli Data Connect _on_
ve _via
söz dizimini kullanır.
İlk sürümümüzdeki şemada değişiklikler yapacaksınız.
Çoka-tek
Uygulamamıza yorumlar ekleyelim. Bunun için Review
tablosu ve User
'da değişiklikler yapalım.
# User table is keyed by Firebase Auth UID.
type User @table {
# `@default(expr: "auth.uid")` sets it to Firebase Auth UID during insert and upsert.
id: String! @default(expr: "auth.uid")
username: String! @col(dataType: "varchar(50)")
# The `user: User!` field in the Review table generates the following one-to-many query field.
# reviews_on_user: [Review!]!
# The `Review` join table the following many-to-many query field.
# movies_via_Review: [Movie!]!
}
# Reviews is a join table tween User and Movie.
# It has a composite primary keys `userUid` and `movieId`.
# A user can leave reviews for many movies. A movie can have reviews from many users.
# User <-> Review is a one-to-many relationship
# Movie <-> Review is a one-to-many relationship
# Movie <-> User is a many-to-many relationship
type Review @table(name: "Reviews", key: ["movie", "user"]) {
user: User!
# The user field adds the following foreign key field. Feel free to uncomment and customize it.
# userUid: String!
movie: Movie!
# The movie field adds the following foreign key field. Feel free to uncomment and customize it.
# movieId: UUID!
rating: Int
reviewText: String
reviewDate: Date! @default(expr: "request.time")
}
Bire çok sorgu
Şimdi _via_
söz dizimini açıklamak için takma ad içeren bir sorguya bakalım.
query UserMoviePreferences($username: String!) @auth(level: USER) {
users(where: { username: { eq: $username } }) {
likedMovies: movies_via_Review(where: { rating: { ge: 4 } }) {
title
genre
}
dislikedMovies: movies_via_Review(where: { rating: { le: 2 } }) {
title
genre
}
}
}
Bire bir
Bu durumu görebilirsiniz. Aşağıda, şemada açıklama amaçlı değişiklikler yapılmıştır.
# Movies
type Movie
@table(name: "Movies", singular: "movie", plural: "movies", key: ["id"]) {
id: UUID! @col(name: "movie_id") @default(expr: "uuidV4()")
title: String!
releaseYear: Int @col(name: "release_year")
genre: String
rating: Int @col(name: "rating")
description: String @col(name: "description")
tags: [String] @col(name: "tags")
}
# Movie Metadata
# Movie - MovieMetadata is a one-to-one relationship
type MovieMetadata
@table(
name: "MovieMetadata"
) {
# @ref creates a field in the current table (MovieMetadata) that holds the primary key of the referenced type
# In this case, @ref(fields: "id") is implied
movie: Movie! @ref
# movieId: UUID <- this is created by the above @ref
director: String @col(name: "director")
}
extend type MovieMetadata {
movieId: UUID! # matches primary key of referenced type
...
}
extend type Movie {
movieMetadata: MovieMetadata # can only be non-nullable on ref side
# conflict-free name, always generated
movieMetadatas_on_movie: MovieMetadata
}
Bire bir sorgu
_on_
söz dizimini kullanarak sorgu oluşturabilirsiniz.
# One to one
query GetMovieMetadata($id: UUID!) @auth(level: PUBLIC) {
movie(id: $id) {
movieMetadatas_on_movie {
director
}
}
}
Çoka çok
Filmler oyunculara, oyuncular da filmlere ihtiyaç duyar. Bu iki tablo arasında MovieActors
birleştirme tablosuyla modelleyebileceğiniz çoklu-çoklu bir ilişki vardır.
# MovieActors Join Table Definition
type MovieActors @table(
key: ["movie", "actor"] # join key triggers many-to-many generation
) {
movie: Movie!
actor: Actor!
}
# generated extensions for the MovieActors join table
extend type MovieActors {
movieId: UUID!
actorId: UUID!
}
# Extensions for Actor and Movie to handle many-to-many relationships
extend type Movie {
movieActors: [MovieActors!]! # standard many-to-one relation to join table
actors: [Actor!]! # many-to-many via join table
movieActors_on_actor: [MovieActors!]!
# since MovieActors joins distinct types, type name alone is sufficiently precise
actors_via_MovieActors: [Actor!]!
}
extend type Actor {
movieActors: [MovieActors!]! # standard many-to-one relation to join table
movies: [Movie!]! # many-to-many via join table
movieActors_on_movie: [MovieActors!]!
movies_via_MovieActors: [Movie!]!
}
Çoka çok sorgu
_via_
söz dizimini açıklamak için takma ad içeren bir sorguya bakalım.
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
}
}
}
Toplama sorguları
Toplamalar nedir ve neden kullanılır?
Toplu alanlar, bir sonuç listesi üzerinde hesaplama yapmanıza olanak tanır. Toplama alanları ile aşağıdakiler gibi işlemler yapabilirsiniz:
- Bir yorumun ortalama puanını bulma
- Alışveriş sepetindeki öğelerin toplam maliyetini bulma
- En yüksek veya en düşük puan alan ürünü bulma
- Mağazanızdaki ürün sayısını sayma
Toplamalar sunucuda gerçekleştirilir. Bu, toplama işlemlerini istemci tarafında hesaplamaya kıyasla çeşitli avantajlar sunar:
- Daha hızlı uygulama performansı (istemci tarafı hesaplamalardan kaçındığınız için)
- Azaltılmış veri çıkış maliyetleri (tüm girişler yerine yalnızca birleştirilmiş sonuçları gönderdiğiniz için)
- Daha iyi güvenlik (müşterilere veri kümesinin tamamı yerine toplu verilere erişim izni verebileceğiniz için)
Toplamalar için örnek şema
Bu bölümde, toplamaların nasıl kullanılacağını açıklamak için iyi bir örnek olan bir mağaza şemalarına geçeceğiz:
type Product @table {
name: String!
manufacturer: String!
quantityInStock: Int!
price: Float!
expirationDate: Date
}
Basit toplamlar
Tüm alanlar için _count
En basit toplama alanı _count
'tür: Sorgunuzla eşleşen satır sayısını döndürür. Data Connect, türünüzün her bir alanı için alan türüne bağlı olarak ilgili toplu alanları oluşturur.
query CountProducts {
products {
_count
}
}
Örneğin, veritabanınızda 5 ürün varsa sonuç şöyle olur:
{
"products": [
{
"_count": 5
}
]
}
Tüm alanların, bu alanda boş olmayan kaç satır olduğunu sayan bir <field>_count
alanı vardır.
query CountProductsWithExpirationDate {
products {
expirationDate_count
}
}
Örneğin, geçerlilik bitiş tarihi olan 3 ürününüz varsa sonuç şöyle olur:
{
"products": [
{
"expirationDate_count": 3
}
]
}
Sayısal alanlar için _min, _max, _sum ve _avg
Sayısal alanlarda (int, float, int64) da <field>_min
, <field>_max
, <field>_sum
ve <field>_avg
bulunur.
query NumericAggregates {
products {
quantityInStock_max
price_min
price_avg
quantityInStock_sum
}
}
Örneğin, aşağıdaki ürünlere sahipseniz:
- A Ürünü:
quantityInStock: 10
,price: 2.99
- B ürünü:
quantityInStock: 5
,price: 5.99
- C ürünü:
quantityInStock: 20
,price: 1.99
Sonuç şöyle olur:
{
"products": [
{
"quantityInStock_max": 20,
"price_min": 1.99,
"price_avg": 3.6566666666666666,
"quantityInStock_sum": 35
}
]
}
Tarihler ve zaman damgalarıyla ilgili _min ve _max
Tarih ve zaman damgası alanlarında <field>_min
ve <field>_max
bulunur.
query DateAndTimeAggregates {
products {
expirationDate_max
expirationDate_min
}
}
Örneğin, aşağıdaki geçerlilik bitiş tarihlerine sahipseniz:
- A ürünü:
2024-01-01
- Ürün B:
2024-03-01
- C ürünü:
2024-02-01
Sonuç şöyle olur:
{
"products": [
{
"expirationDate_max": "2024-03-01",
"expirationDate_min": "2024-01-01"
}
]
}
Farklı
distinct
bağımsız değişkeni, bir alan (veya alan kombinasyonu) için tüm benzersiz değerleri almanıza olanak tanır. Örneğin:
query ListDistinctManufacturers {
products(distinct: true) {
manufacturer
}
}
Örneğin, aşağıdaki üreticilere sahipseniz:
- A ürünü:
manufacturer: "Acme"
- Ürün B:
manufacturer: "Beta"
- C ürünü:
manufacturer: "Acme"
Sonuç şöyle olur:
{
"products": [
{ "manufacturer": "Acme" },
{ "manufacturer": "Beta" }
]
}
Ayrıca, farklı değerleri toplamak için toplu alanlarda distinct
bağımsız değişkenini de kullanabilirsiniz. Örneğin:
query CountDistinctManufacturers {
products {
manufacturer_count(distinct: true)
}
}
Örneğin, aşağıdaki üreticilere sahipseniz:
- A ürünü:
manufacturer: "Acme"
- Ürün B:
manufacturer: "Beta"
- C ürünü:
manufacturer: "Acme"
Sonuç şöyle olur:
{
"products": [
{
"manufacturer_count": 2
}
]
}
Gruplandırılmış toplamalar
Bir türde toplu ve toplu olmayan alanların bir karışımını seçerek gruplandırılmış toplama işlemi gerçekleştirirsiniz. Bu işlem, toplu olmayan alanlar için aynı değere sahip tüm eşleşen satırları gruplandırır ve bu grup için toplu alanları hesaplar. Örneğin:
query MostExpensiveProductByManufacturer {
products {
manufacturer
price_max
}
}
Örneğin, aşağıdaki ürünlere sahipseniz:
- A Ürünü:
manufacturer: "Acme"
,price: 2.99
- B ürünü:
manufacturer: "Beta"
,price: 5.99
- C ürünü:
manufacturer: "Acme"
,price: 1.99
Sonuç şöyle olur:
{
"products": [
{ "manufacturer": "Acme", "price_max": 2.99 },
{ "manufacturer": "Beta", "price_max": 5.99 }
]
}
Gruplandırılmış toplama içeren having
ve where
Yalnızca belirtilen ölçütleri karşılayan grupları döndürmek için having
ve where
bağımsız değişkenini de kullanabilirsiniz.
having
, grupları toplu alanlarına göre filtrelemenize olanak tanır.where
, satırları toplu olmayan alanlara göre filtrelemenize olanak tanır.
query FilteredMostExpensiveProductByManufacturer {
products(having: {price_max: {ge: 2.99}}) {
manufacturer
price_max
}
}
Örneğin, aşağıdaki ürünlere sahipseniz:
- A Ürünü:
manufacturer: "Acme"
,price: 2.99
- B ürünü:
manufacturer: "Beta"
,price: 5.99
- C ürünü:
manufacturer: "Acme"
,price: 1.99
Sonuç şöyle olur:
{
"products": [
{ "manufacturer": "Acme", "price_max": 2.99 },
{ "manufacturer": "Beta", "price_max": 5.99 }
]
}
Tablolar genelinde toplanır.
Toplama alanları, verilerinizle ilgili karmaşık soruları yanıtlamak için oluşturulan bire çok ilişki alanlarıyla birlikte kullanılabilir. Aşağıda, örneklerde kullanabileceğimiz ayrı bir Manufacturer
tablosu içeren değiştirilmiş bir şema verilmiştir:
type Product @table {
name: String!
manufacturer: Manufacturer!
quantityInStock: Int!
price: Float!
expirationDate: Date
}
type Manufacturer @table {
name: String!
headquartersCountry: String!
}
Artık bir üreticinin kaç ürün ürettiğini bulmak gibi işlemleri yapmak için toplu alanları kullanabiliriz:
query GetProductCount($id: UUID) {
manufacturers {
name
products_on_manufacturer {
_count
}
}
}
Örneğin, aşağıdaki üreticilere sahipseniz:
- A üreticisi:
name: "Acme"
,products_on_manufacturer: 2
- Üretici B:
name: "Beta"
,products_on_manufacturer: 1
Sonuç şöyle olur:
{
"manufacturers": [
{ "name": "Acme", "products_on_manufacturer": { "_count": 2 } },
{ "name": "Beta", "products_on_manufacturer": { "_count": 1 } }
]
}
Film eleştirisi veritabanı için mutasyonlar
Daha önce de belirtildiği gibi, şemanızda bir tablo tanımladığınızda Data Connect, her tablo için temel, gizli mutasyonlar oluşturur.
type Movie @table { ... }
extend type Mutation {
# Insert a row into the movie table.
movie_insert(...): Movie_Key!
# Upsert a row into movie."
movie_upsert(...): Movie_Key!
# Update a row in Movie. Returns null if a row with the specified id/key does not exist
movie_update(...): Movie_Key
# Update rows based on a filter in Movie.
movie_updateMany(...): Int!
# Delete a single row in Movie. Returns null if a row with the specified id/key does not exist
movie_delete(...): Movie_Key
# Delete rows based on a filter in Movie.
movie_deleteMany(...): Int!
}
Bu sayede, giderek daha karmaşık temel CRUD işlemlerini uygulayabilirsiniz. Bunu hızlıca beş kez söyle.
@transaction
yönergesi
Bu yönerge, bir mutasyonun her zaman bir veritabanı işleminde çalıştırılmasını zorunlu kılar.
@transaction
içeren mutasyonların tamamen başarılı veya tamamen başarısız olacağı garanti edilir. İşlemdeki alanlardan herhangi biri başarısız olursa tüm işlem geri alınır. İstemci açısından, tüm istek bir istek hatasıyla başarısız olmuş ve yürütme işlemi başlamamış gibi davranır.
@transaction
içermeyen mutasyonlar, her bir kök alanı sırayla birbiri ardına yürütür. Tüm hataları kısmi alan hataları olarak gösterir ancak sonraki yürütmelerin etkilerini göstermez.
Oluştur
Temel oluşturma işlemlerini yapalım.
# Create a movie based on user input
mutation CreateMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
movie_insert(data: {
title: $title
releaseYear: $releaseYear
genre: $genre
rating: $rating
})
}
# Create a movie with default values
mutation CreateMovie2 {
movie_insert(data: {
title: "Sherlock Holmes"
releaseYear: 2009
genre: "Mystery"
rating: 5
})
}
Veya bir upsert.
# Movie upsert using combination of variables and literals
mutation UpsertMovie($title: String!) {
movie_upsert(data: {
title: $title
releaseYear: 2009
genre: "Mystery"
rating: 5
genre: "Mystery/Thriller"
})
}
Güncelleme yapma
Güncellemeleri aşağıda bulabilirsiniz. Yapımcılar ve yönetmenler, bu ortalama puanların trende uygun olmasını ister.
movie_update
alanı, bir kaydı tanımlamak için beklenen bir id
bağımsız değişkeni ve bu güncellemede değerleri ayarlamak için kullanabileceğiniz bir data
alanı içerir.
mutation UpdateMovie(
$id: UUID!,
$genre: String!,
$rating: Int!,
$description: String!
) {
movie_update(id: $id,
data: {
genre: $genre
rating: $rating
description: $description
})
}
Birden fazla güncelleme yapmak için movie_updateMany
alanını kullanın.
# Multiple updates (increase all ratings of a genre)
mutation IncreaseRatingForGenre($genre: String!, $rating: Int!) {
movie_updateMany(
where: { genre: { eq: $genre } },
data:
{
rating: $rating
})
}
_update
ile artma, azalma, ekleme ve önce ekleme işlemlerini kullanma
_update
ve _updateMany
mutasyonlarında data:
'de değerleri açıkça ayarlayabilirsiniz ancak değerleri güncellemek için genellikle artma gibi bir operatör uygulamak daha mantıklı olur.
Önceki güncelleme örneğini değiştirmek için belirli bir filmin puanını artırmak istediğinizi varsayalım. rating_update
söz dizimini inc
operatörüyle kullanabilirsiniz.
mutation UpdateMovie(
$id: UUID!,
$ratingIncrement: Int!
) {
movie_update(id: $id, data: {
rating_update: {
inc: $ratingIncrement
}
})
}
Data Connect, alan güncellemeleri için aşağıdaki operatörleri destekler:
Int
,Int64
veFloat
veri türlerini artırmak içininc
Int
,Int64
veFloat
veri türlerini azaltmak içindec
- Vektör listeleri hariç liste türlerine eklemek için
append
- Vektör listeleri hariç liste türlerine ön ek olarak eklenmek için
prepend
Silme işlemleri gerçekleştirme
Film verilerini silebilirsiniz. Film koruma uzmanları, fiziksel filmlerin mümkün olduğunca uzun süre korunmasını ister.
# Delete by key
mutation DeleteMovie($id: UUID!) {
movie_delete(id: $id)
}
Burada _deleteMany
kullanabilirsiniz.
# Multiple deletes
mutation DeleteUnpopularMovies($minRating: Int!) {
movie_deleteMany(where: { rating: { le: $minRating } })
}
İlişkilerde mutasyon yazma
Bir ilişkide örtülü _upsert
mutasyonunun nasıl kullanıldığını gözlemleyin.
# Create or update a one to one relation
mutation MovieMetadataUpsert($movieId: UUID!, $director: String!) {
movieMetadata_upsert(
data: { movie: { id: $movieId }, director: $director }
)
}
Data Connect'ün field_expr
söz dizimini kullanarak değer sağlamasına izin verin
Anahtar skaler ve sunucu değerleri bölümünde belirtildiği gibi, şemanızı, sunucunun istemci isteklerine yanıt olarak id
ve tarihler gibi ortak alanlar için değerleri dolduracağı şekilde tasarlayabilirsiniz.
Ayrıca, istemci uygulamalarından Data Connect request
nesnelerinde gönderilen kullanıcı kimlikleri gibi verilerden yararlanabilirsiniz.
Mutasyonlar uygularken sunucu tarafından oluşturulan güncellemeleri tetiklemek veya isteklerdeki verilere erişmek için field_expr
söz dizimini kullanın. Örneğin, bir istekte saklanan uid
yetkilendirmesini bir _upsert
işlemine iletmek için userId_expr
alanına "auth.uid"
değerini iletin.
# Add a movie to the user's favorites list
mutation AddFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId })
}
# Remove a movie from the user's favorites list
mutation DeleteFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie_delete(key: { userId_expr: "auth.uid", movieId: $movieId })
}
Alternatif olarak, tanıdık bir yapılacaklar listesi uygulamasında yeni bir yapılacaklar listesi oluştururken id_expr
değerini ileterek sunucunun liste için otomatik olarak bir UUID oluşturmasını sağlayabilirsiniz.
mutation CreateTodoListWithFirstItem(
$listName: String!
) @transaction {
# Step 1
todoList_insert(data: {
id_expr: "uuidV4()", # <-- auto-generated. Or a column-level @default on `type TodoList` will also work
name: $listName,
})
}
Daha fazla bilgi için skalar referansında _Expr
skalarlarına bakın.
Yetkilendirme verisi arama sorguları
Data Connect mutasyonları, önce veritabanını sorgulayarak ve sorgunun sonuçlarını CEL ifadeleriyle doğrulayarak yetkilendirilebilir. Bu, örneğin bir tabloya yazarken başka bir tablodaki bir satırın içeriğini kontrol etmeniz gerektiğinde kullanışlıdır.
Bu özellik şunları destekler:
- Alanların içeriğini değerlendirmenize ve bu değerlendirmenin sonuçlarına göre işlem yapmanıza olanak tanıyan
@check
yönergesi:- Bir mutasyonla tanımlanan oluşturma, güncelleme ve silme işlemlerine devam edin
- Sorgu sonuçlarını döndürmeye devam edin
- Müşteri kodunuzda farklı mantıklar yürütmek için döndürülen değerleri kullanma
- Sorgu sonuçlarını kablo protokolü sonuçlarından çıkarmanıza olanak tanıyan
@redact
yönergesi.
Bu özellikler yetkilendirme akışları için yararlıdır.
Eşdeğer SQL şeması
-- Movies Table
CREATE TABLE Movies (
movie_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
title VARCHAR(255) NOT NULL,
release_year INT,
genre VARCHAR(30),
rating INT,
description TEXT,
tags TEXT[]
);
-- Movie Metadata Table
CREATE TABLE MovieMetadata (
movie_id UUID REFERENCES Movies(movie_id) UNIQUE,
director VARCHAR(255) NOT NULL,
PRIMARY KEY (movie_id)
);
-- Actors Table
CREATE TABLE Actors (
actor_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
name VARCHAR(30) NOT NULL
);
-- MovieActor Join Table for Many-to-Many Relationship
CREATE TABLE MovieActor (
movie_id UUID REFERENCES Movies(movie_id),
actor_id UUID REFERENCES Actors(actor_id),
role VARCHAR(50) NOT NULL, # "main" or "supporting"
PRIMARY KEY (movie_id, actor_id),
FOREIGN KEY (movie_id) REFERENCES Movies(movie_id),
FOREIGN KEY (actor_id) REFERENCES Actors(actor_id)
);
-- Users Table
CREATE TABLE Users (
user_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
user_auth VARCHAR(255) NOT NULL
username VARCHAR(30) NOT NULL
);
-- Reviews Table
CREATE TABLE Reviews (
review_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
user_id UUID REFERENCES Users(user_id),
movie_id UUID REFERENCES Movies(movie_id),
rating INT,
review_text TEXT,
review_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE (movie_id, user_id)
FOREIGN KEY (user_id) REFERENCES Users(user_id),
FOREIGN KEY (movie_id) REFERENCES Movies(movie_id)
);
-- Self Join Example for Movie Sequel Relationship
ALTER TABLE Movies
ADD COLUMN sequel_to UUID REFERENCES Movies(movie_id);
Sırada ne var?
- Yetkilendirme ve doğrulama ile sorgularınızı ve mutasyonlarınızı nasıl güvenli hale getireceğinizi öğrenin.
- Sorgularınızı ve mutasyonlarınızı otomatik olarak oluşturulan web SDK'sından, Android SDK'sından, iOS SDK'sından ve Flutter SDK'sından nasıl çağıracağınızı öğrenin.