Firebase Data Connect به شما امکان می دهد برای نمونه های PostgreSQL خود که با Google Cloud SQL مدیریت می شوند، رابط ایجاد کنید. این رابطها ترکیبی از طرحواره، پرسشها و جهشها برای استفاده از دادههای شما هستند.
راهنمای شروع یک طرح برنامه بررسی فیلم را برای PostgreSQL معرفی کرد و این راهنما نگاهی عمیق تر به نحوه طراحی طرحواره های Data Connect برای PostgreSQL دارد.
این راهنما پرس و جوها و جهش های Data Connect را با نمونه های طرحواره جفت می کند. چرا پرس و جوها (و جهش ها ) را در راهنمای طرحواره های Data Connect مورد بحث قرار می دهیم؟ مانند سایر پلتفرمهای مبتنی بر GraphQL، Firebase Data Connect یک پلتفرم توسعه اولین پرس و جو است، بنابراین بهعنوان یک توسعهدهنده، در مدلسازی دادههای خود به دادههایی فکر میکنید که مشتریانتان به آن نیاز دارند، که تا حد زیادی بر طرح دادهای که برای پروژه خود ایجاد میکنید، تأثیر میگذارد.
این راهنما با طرحی جدید برای بررسی فیلم شروع میشود، سپس پرسشها و جهشهای حاصل از آن طرح را پوشش میدهد و در نهایت فهرستی از SQL معادل طرح اصلی Data Connect ارائه میدهد.
طرحی برای یک برنامه بررسی فیلم
تصور کنید می خواهید سرویسی بسازید که به کاربران اجازه می دهد نظرات فیلم ها را ارسال و مشاهده کنند.
برای چنین اپلیکیشنی به یک طرح اولیه نیاز دارید. بعداً این طرح را برای ایجاد پرس و جوهای رابطه ای پیچیده گسترش خواهید داد.
میز فیلم
طرح فیلم ها حاوی دستورالعمل های اصلی مانند:
-
@table(name)
و@col(name)
برای سفارشی کردن جدول SQL و نام ستون. Data Connect نامهای snake_case را در صورت عدم مشخص کردن ایجاد میکند. -
@col(dataType)
برای سفارشی کردن انواع ستون SQL. -
@default
برای پیکربندی مقادیر پیشفرض ستون SQL در حین درج.
برای جزئیات بیشتر، اسناد مرجع برای @table
، @col
، @default
را بررسی کنید.
# 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
}
مقادیر سرور و اسکالرهای کلیدی
قبل از دیدن برنامه بررسی فیلم، اجازه دهید مقادیر سرور Data Connect و اسکالرهای کلیدی را معرفی کنیم.
با استفاده از مقادیر سرور ، میتوانید به طور مؤثر به سرور اجازه دهید فیلدهای جداول شما را با استفاده از مقادیر ذخیره شده یا قابل محاسبه بر اساس عبارات سمت سرور به صورت پویا پر کند. به عنوان مثال، میتوانید با استفاده از عبارت updatedAt: Timestamp! @default(expr: "request.time")
.
اسکالرهای کلیدی شناسه های شی مختصر هستند که Data Connect به طور خودکار از فیلدهای کلیدی در طرحواره های شما جمع آوری می کند. اسکالرهای کلیدی در مورد کارایی هستند و به شما امکان می دهند در یک تماس اطلاعاتی درباره هویت و ساختار داده های خود پیدا کنید. آنها به ویژه زمانی مفید هستند که می خواهید اقدامات متوالی را روی رکوردهای جدید انجام دهید و به یک شناسه منحصر به فرد برای ارسال به عملیات آینده نیاز دارید، و همچنین زمانی که می خواهید به کلیدهای رابطه ای برای انجام عملیات پیچیده تر اضافی دسترسی داشته باشید.
جدول فراداده فیلم
اکنون بیایید کارگردانان فیلم را ردیابی کنیم و همچنین یک رابطه یک به یک با Movie
برقرار کنیم.
فیلد مرجع را برای تعریف یک رابطه اضافه کنید.
می توانید از دستور @ref
برای سفارشی کردن محدودیت کلید خارجی استفاده کنید.
-
@ref(fields)
برای تعیین فیلدهای کلید خارجی. -
@ref(references)
برای تعیین فیلدهای ارجاع شده در جدول هدف. این مرجع به طور پیش فرض کلید اصلی است، اما فیلدهای با@unique
نیز پشتیبانی می شوند.
برای جزئیات بیشتر، اسناد مرجع برای @ref
را بررسی کنید.
# Movie Metadata
# Movie - MovieMetadata is a one-to-one relationship
type MovieMetadata @table {
# @unique ensures that each Movie only has one MoiveMetadata.
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
}
بازیگر و بازیگر سینما
در مرحله بعد، شما می خواهید بازیگران در فیلم های شما بازی کنند، و از آنجایی که بین فیلم ها و بازیگران رابطه چند به چند دارید، یک جدول پیوستن ایجاد کنید.
# 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
}
کاربر
در نهایت، کاربران برای برنامه شما.
# Users
# Suppose a user can leave reviews for movies
type User @table {
id: String! @default(expr: "auth.uid")
username: String! @col(dataType: "varchar(50)")
}
انواع داده های پشتیبانی شده
Data Connect از انواع داده های اسکالر زیر پشتیبانی می کند، با انتساب به انواع PostgreSQL با استفاده از @col(dataType:)
.
نوع Data Connect | GraphQL توکار نوع یا نوع سفارشی Data Connect | نوع پیش فرض PostgreSQL | پشتیبانی از انواع PostgreSQL (نام مستعار داخل پرانتز) |
---|---|---|---|
رشته | GraphQL | متن | متن بیت (n)، varbit (n) char(n)، varchar(n) |
بین المللی | GraphQL | بین المللی | Int2 (کوچک، سریال کوچک)، int4 (عدد صحیح، int، سریال) |
شناور | GraphQL | شناور8 | float4 (واقعی) float8 (دقت دوگانه) عددی (اعشاری) |
بولی | GraphQL | بولی | بولی |
UUID | سفارشی | uuid | uuid |
Int64 | سفارشی | bigint | int8 (bigint، bigserial) عددی (اعشاری) |
تاریخ | سفارشی | تاریخ | تاریخ |
مهر زمان | سفارشی | timestamptz | timestamptz توجه: اطلاعات منطقه زمانی محلی ذخیره نمی شود. |
بردار | سفارشی | بردار | بردار به انجام جستجوی شباهت برداری با Vertex AI مراجعه کنید. |
- GraphQL
List
به یک آرایه یک بعدی نگاشت می شود.- برای مثال،
[Int]
بهint5[]
,[Any]
بهjsonb[]
نقشه میدهد. - Data Connect از آرایه های تو در تو پشتیبانی نمی کند.
- برای مثال،
کوئری ها و جهش های ضمنی و از پیش تعریف شده
جستارها و جهش های Data Connect شما مجموعه ای از پرس و جوهای ضمنی و جهش های ضمنی ایجاد شده توسط Data Connect را بر اساس انواع و روابط نوع در طرح شما گسترش می دهند. هر زمان که شما طرحواره خود را ویرایش می کنید، پرس و جوها و جهش های ضمنی توسط ابزارهای محلی ایجاد می شوند.
در فرآیند توسعه خود، پرس و جوهای از پیش تعریف شده و جهش های از پیش تعریف شده را بر اساس این عملیات ضمنی پیاده سازی خواهید کرد.
پرس و جو ضمنی و نامگذاری جهش
Data Connect نام های مناسب را برای پرس و جوها و جهش های ضمنی از اعلان های نوع طرحواره شما استنتاج می کند. به عنوان مثال، با کار با یک منبع PostgreSQL، اگر جدولی به نام Movie
تعریف کنید، سرور به صورت ضمنی تولید می کند:
- پرسوجوها برای جدولهای تکی با نامهای دوستانه
movie
(مفرد، برای بازیابی نتایج منفرد با عبور ارگهایی مانندeq
) وmovies
(جمع، برای بازیابی فهرستهای نتایج، ارگهایی مانندgt
و عملیاتی مانندorderby
) استفاده میکنند. Data Connect همچنین پرس و جوهایی را برای عملیات های چند جدولی و رابطه ای با نام های صریح مانندactors_on_movies
یاactors_via_actormovie
ایجاد می کند. - جهش هایی با نام
movie_insert
,movie_upsert
...
زبان تعریف طرحواره همچنین به شما این امکان را می دهد که با استفاده از آرگومان های دستوری singular
و plural
، نام عملیات را به صراحت تنظیم کنید.
دستورالعمل برای پرس و جو و جهش
علاوه بر دستورالعملهایی که در تعریف انواع و جداول استفاده میکنید، Data Connect دستورات @auth
، @check
، @redact
و @transaction
را برای تقویت رفتار کوئریها و جهشها ارائه میکند.
بخشنامه | قابل اجرا برای | توضیحات |
---|---|---|
@auth | پرس و جو و جهش | خط مشی احراز هویت را برای یک پرس و جو یا جهش تعریف می کند. راهنمای مجوز و گواهینامه را ببینید. |
@check | درخواست جستجوی داده های مجوز | بررسی می کند که فیلدهای مشخص شده در نتایج پرس و جو وجود دارد. یک عبارت Common Expression Language (CEL) برای آزمایش مقادیر فیلد استفاده می شود. راهنمای مجوز و گواهینامه را ببینید. |
@redact | پرس و جوها | بخشی از پاسخ مشتری را ویرایش می کند. راهنمای مجوز و گواهینامه را ببینید. |
@transaction | جهش ها | الزام می کند که یک جهش همیشه در یک تراکنش پایگاه داده اجرا شود. نمونه های جهش برنامه فیلم را ببینید. |
پرس و جو برای پایگاه داده نقد و بررسی فیلم
شما یک کوئری Data Connect را با اعلان نوع عملیات پرس و جو، نام عملیات، آرگومان های عملیات صفر یا بیشتر، و صفر یا بیشتر دستورالعمل با آرگومان ها تعریف می کنید.
در شروع سریع، پرس و جوی مثال listEmails
هیچ پارامتری نداشت. البته در بسیاری از موارد داده های ارسال شده به فیلدهای پرس و جو پویا خواهند بود. میتوانید از نحو $variableName
برای کار با متغیرها بهعنوان یکی از اجزای تعریف پرسوجو استفاده کنید.
بنابراین پرس و جو زیر دارد:
- تعریف نوع
query
- نام عملیات
ListMoviesByGenre
(پرس و جو). - یک آرگومان عملیات
$genre
متغییر - یک دستورالعمل واحد،
@auth
.
query ListMoviesByGenre($genre: String!) @auth(level: USER)
هر آرگومان پرس و جو نیاز به یک اعلان نوع، یک نوع داخلی مانند String
، یا یک نوع سفارشی، طرحواره تعریف شده مانند Movie
دارد.
بیایید به امضای پرس و جوهای پیچیده تر نگاه کنیم. شما با معرفی عبارات ارتباطی قدرتمند و مختصر موجود در پرسوجوهای ضمنی که میتوانید در پرسوجوهای از پیش تعریفشده خود بر روی آنها بسازید، به پایان میرسید.
اسکالرهای کلیدی در پرس و جوها
اما ابتدا یک نکته در مورد اسکالرهای کلیدی.
Data Connect نوع خاصی را برای اسکالرهای کلیدی تعریف می کند که با _Key
مشخص می شود. به عنوان مثال، نوع اسکالر کلید برای جدول Movie
ما Movie_Key
است.
شما اسکالرهای کلیدی را به عنوان پاسخی که توسط اکثر جهشهای ضمنی برگردانده میشود، یا البته از کوئریهایی که تمام فیلدهای مورد نیاز برای ساختن کلید اسکالر را بازیابی کردهاید، بازیابی میکنید.
پرسوجوهای خودکار منفرد، مانند movie
در مثال در حال اجرا، از یک آرگومان کلیدی پشتیبانی میکنند که یک اسکالر کلیدی را میپذیرد.
شما ممکن است یک اسکالر کلیدی را به صورت تحت اللفظی پاس کنید. اما، می توانید متغیرهایی را برای ارسال اسکالرهای کلیدی به عنوان ورودی تعریف کنید.
query GetMovie($myKey: Movie_Key!) {
movie(key: $myKey) { title }
}
اینها را می توان در درخواست JSON مانند این (یا سایر قالب های سریال سازی) ارائه کرد:
{
# …
"variables": {
"myKey": {"foo": "some-string-value", "bar": 42}
}
}
به لطف تجزیه اسکالر سفارشی، یک Movie_Key
نیز می تواند با استفاده از نحو شی که ممکن است حاوی متغیرهایی باشد ساخته شود. این بیشتر زمانی مفید است که بخواهید به دلایلی اجزای جداگانه را به متغیرهای مختلف تقسیم کنید.
نام مستعار در پرس و جوها
Data Connect از نام مستعار GraphQL در کوئری ها پشتیبانی می کند. با نام مستعار، نام داده هایی را که در نتایج یک پرس و جو برگردانده می شوند، تغییر می دهید. یک کوئری Data Connect می تواند چندین فیلتر یا عملیات پرس و جوی دیگر را در یک درخواست کارآمد به سرور اعمال کند و به طور موثر چندین «پرس و جوی فرعی» را همزمان صادر کند. برای جلوگیری از تصادم نام در مجموعه داده های برگشتی، از نام مستعار برای تشخیص پرس و جوهای فرعی استفاده می کنید.
در اینجا یک جستجو وجود دارد که در آن یک عبارت از نام مستعار mostPopular
استفاده می کند.
query ReviewTopPopularity($genre: String) {
mostPopular: review(first: {
where: {genre: {eq: $genre}},
orderBy: {popularity: DESC}
}) { … }
}
پرس و جوهای ساده با فیلتر
پرس و جوهای 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
}
}
query MoviesByReleaseYear($min: Int, $max: Int) {
movies(where: {releaseYear: {le: $max, ge: $min}}, orderBy: [{releaseYear: ASC}]) { … }
}
عملگرهای limit
و offset
(پرس و جوهای مفرد، جمع)
می توانید صفحه بندی را روی نتایج انجام دهید. این آرگومانها پذیرفته میشوند اما به نتایج بازگردانده نمیشوند.
query MoviesTop10 {
movies(orderBy: [{ rating: DESC }], limit: 10) {
# graphql: list the fields from the results to return
title
}
}
شامل زمینه های آرایه می شود
می توانید آزمایش کنید که یک فیلد آرایه شامل یک آیتم مشخص شده باشد.
# 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
}
}
عملیات رشته و عبارات منظم
جستارهای شما می توانند از عملیات جستجو و مقایسه رشته ای معمولی از جمله عبارات منظم استفاده کنند. توجه داشته باشید برای کارایی شما چندین عملیات را در اینجا دسته بندی می کنید و آنها را با نام مستعار رفع می کنید.
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}}}) {...}
}
or
و and
برای فیلترهای ترکیبی
or
و and
برای منطق پیچیده تر استفاده کنید.
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 Connect می توانند به داده ها بر اساس روابط بین جداول دسترسی داشته باشند. شما می توانید از روابط شی (یک به یک) یا آرایه (یک به چند) تعریف شده در طرحواره خود برای ایجاد پرس و جوهای تودرتو، یعنی واکشی داده برای یک نوع به همراه داده های یک نوع تودرتو یا مرتبط استفاده کنید.
چنین پرس و جوهایی از جادویی Data Connect _on_
و _via
syntax در جستارهای ضمنی تولید شده استفاده می کنند.
شما تغییراتی در طرحواره از نسخه اولیه ما ایجاد خواهید کرد.
بسیاری به یک
بیایید نظرات را به برنامه خود اضافه کنیم، با جدول Review
و تغییراتی در User
.
# 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")
}
پرس و جو برای خیلی به یک
حالا بیایید به یک پرس و جو نگاه کنیم، با نام مستعار، برای نشان دادن نحو _via_
.
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
}
}
}
یک به یک
می توانید الگو را ببینید. در زیر، این طرح برای تصویر اصلاح شده است.
# 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
}
یک به یک پرس و جو کنید
می توانید با استفاده از نحو _on_
پرس و جو کنید.
# One to one
query GetMovieMetadata($id: UUID!) @auth(level: PUBLIC) {
movie(id: $id) {
movieMetadatas_on_movie {
director
}
}
}
خیلی به خیلی ها
فیلم ها به بازیگر نیاز دارند و بازیگران به فیلم. آنها روابط بسیار زیادی دارند که می توانید با جدول پیوستن MovieActors
مدل کنید.
# 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!]!
}
پرس و جو برای بسیاری از بسیاری
بیایید به یک پرس و جو با نام مستعار نگاه کنیم تا نحو _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 Connect جهش های ضمنی اساسی را برای هر جدول ایجاد می کند.
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!
}
با استفاده از این موارد، می توانید موارد پیچیده هسته ای CRUD را پیاده سازی کنید. پنج بار سریع بگو!
دستورالعمل @transaction
این دستورالعمل الزام می کند که یک جهش همیشه در یک تراکنش پایگاه داده اجرا شود.
جهش با @transaction
تضمین شده است که یا به طور کامل موفق شود یا به طور کامل شکست بخورد. اگر هر یک از فیلدهای داخل تراکنش از کار بیفتد، کل تراکنش برگردانده می شود. از نقطه نظر مشتری، هر شکست به گونه ای رفتار می کند که گویی کل درخواست با یک خطای درخواست شکست خورده است و اجرا آغاز نشده است.
جهش های بدون @transaction
هر فیلد ریشه را یکی پس از دیگری به ترتیب اجرا می کنند. هر گونه خطا را به عنوان خطای میدانی جزئی نشان می دهد، اما تاثیرات اجرای بعدی را نه.
ایجاد کنید
بیایید کارهای اساسی انجام دهیم.
# 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
})
}
یا یک تاپیک
# 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"
})
}
به روز رسانی را انجام دهید
در اینجا به روز رسانی است. تهیهکنندگان و کارگردانان مطمئناً امیدوارند که این رتبهبندیهای متوسط رو به رشد باشد.
mutation UpdateMovie(
$id: UUID!,
$genre: String!,
$rating: Int!,
$description: String!
) {
movie_update(id: $id, data: {
genre: $genre
rating: $rating
description: $description
})
}
# Multiple updates (increase all ratings of a genre)
mutation IncreaseRatingForGenre($genre: String!, $ratingIncrement: Int!) {
movie_updateMany(
where: { genre: { eq: $genre } },
update: { rating: { inc: $ratingIncrement } }
)
}
حذف ها را انجام دهید
البته می توانید داده های فیلم را حذف کنید. محافظان فیلم مطمئناً مایلند که فیلمهای فیزیکی تا زمانی که ممکن است نگهداری شوند.
# Delete by key
mutation DeleteMovie($id: UUID!) {
movie_delete(id: $id)
}
در اینجا می توانید از _deleteMany
استفاده کنید.
# Multiple deletes
mutation DeleteUnpopularMovies($minRating: Int!) {
movie_deleteMany(where: { rating: { le: $minRating } })
}
جهش را روی روابط بنویسید
نحوه استفاده از جهش _upsert
ضمنی را در یک رابطه مشاهده کنید.
# Create or update a one to one relation
mutation MovieMetadataUpsert($movieId: UUID!, $director: String!) {
movieMetadata_upsert(
data: { movie: { id: $movieId }, director: $director }
)
}
درخواست جستجوی داده های مجوز
جهش های Data Connect را می توان با پرس و جو در پایگاه داده و تأیید نتایج پرس و جو با عبارات CEL مجاز کرد. این زمانی مفید است که، برای مثال، در حال نوشتن روی یک جدول هستید، و باید محتویات یک ردیف را در جدول دیگری بررسی کنید.
این ویژگی پشتیبانی می کند:
- دستورالعمل
@check
، که به شما امکان میدهد محتویات فیلدها را ارزیابی کنید و بر اساس نتایج چنین ارزیابی:- ایجاد، به روز رسانی و حذف های تعریف شده توسط یک جهش را ادامه دهید
- برای بازگرداندن نتایج یک پرس و جو ادامه دهید
- از مقادیر برگشتی برای اجرای منطق های مختلف در کد مشتری خود استفاده کنید
- دستورالعمل
@redact
، که به شما امکان می دهد نتایج پرس و جو را از نتایج پروتکل سیمی حذف کنید.
این ویژگی ها برای جریان های مجوز مفید هستند.
طرحواره SQL معادل
-- 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);
بعدش چی؟
- بیاموزید که چگونه پرس و جوها و جهش های خود را با مجوز و گواهی ایمن کنید.
- با نحوه فراخوانی پرسشها و جهشهای خود از یک وب SDK ، Android SDK ، iOS SDK و Flutter SDK که بهطور خودکار ایجاد میشود، بیاموزید.
Firebase Data Connect به شما امکان می دهد برای نمونه های PostgreSQL خود که با Google Cloud SQL مدیریت می شوند، رابط ایجاد کنید. این رابطها ترکیبی از طرحواره، پرسشها و جهشها برای استفاده از دادههای شما هستند.
راهنمای شروع یک طرح برنامه بررسی فیلم را برای PostgreSQL معرفی کرد و این راهنما نگاهی عمیق تر به نحوه طراحی طرحواره های Data Connect برای PostgreSQL دارد.
این راهنما پرس و جوها و جهش های Data Connect را با نمونه های طرحواره جفت می کند. چرا پرس و جوها (و جهش ها ) را در راهنمای طرحواره های Data Connect مورد بحث قرار می دهیم؟ مانند سایر پلتفرمهای مبتنی بر GraphQL، Firebase Data Connect یک پلتفرم توسعه اولین پرس و جو است، بنابراین بهعنوان یک توسعهدهنده، در مدلسازی دادههای خود به دادههایی فکر میکنید که مشتریانتان به آن نیاز دارند، که تا حد زیادی بر طرح دادهای که برای پروژه خود ایجاد میکنید، تأثیر میگذارد.
این راهنما با طرحی جدید برای بررسی فیلم شروع میشود، سپس پرسشها و جهشهای حاصل از آن طرح را پوشش میدهد و در نهایت فهرستی از SQL معادل طرح اصلی Data Connect ارائه میدهد.
طرحی برای یک برنامه بررسی فیلم
تصور کنید می خواهید سرویسی بسازید که به کاربران اجازه می دهد نظرات فیلم ها را ارسال و مشاهده کنند.
برای چنین اپلیکیشنی به یک طرح اولیه نیاز دارید. بعداً این طرح را برای ایجاد پرس و جوهای رابطه ای پیچیده گسترش خواهید داد.
میز فیلم
طرح فیلم ها حاوی دستورالعمل های اصلی مانند:
-
@table(name)
و@col(name)
برای سفارشی کردن جدول SQL و نام ستون. Data Connect نامهای snake_case را در صورت عدم مشخص کردن ایجاد میکند. -
@col(dataType)
برای سفارشی کردن انواع ستون SQL. -
@default
برای پیکربندی مقادیر پیشفرض ستون SQL در حین درج.
برای جزئیات بیشتر، اسناد مرجع برای @table
، @col
، @default
را بررسی کنید.
# 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
}
مقادیر سرور و اسکالرهای کلیدی
قبل از دیدن برنامه بررسی فیلم، اجازه دهید مقادیر سرور Data Connect و اسکالرهای کلیدی را معرفی کنیم.
با استفاده از مقادیر سرور ، میتوانید به طور مؤثر به سرور اجازه دهید فیلدهای جداول شما را با استفاده از مقادیر ذخیره شده یا قابل محاسبه بر اساس عبارات سمت سرور به صورت پویا پر کند. به عنوان مثال، میتوانید با استفاده از عبارت updatedAt: Timestamp! @default(expr: "request.time")
.
اسکالرهای کلیدی شناسه های شی مختصر هستند که Data Connect به طور خودکار از فیلدهای کلیدی در طرحواره های شما جمع آوری می کند. اسکالرهای کلیدی در مورد کارایی هستند و به شما امکان می دهند در یک تماس اطلاعاتی درباره هویت و ساختار داده های خود پیدا کنید. آنها به ویژه زمانی مفید هستند که می خواهید اقدامات متوالی را روی رکوردهای جدید انجام دهید و به یک شناسه منحصر به فرد برای ارسال به عملیات آینده نیاز دارید، و همچنین زمانی که می خواهید به کلیدهای رابطه ای برای انجام عملیات پیچیده تر اضافی دسترسی داشته باشید.
جدول فراداده فیلم
اکنون بیایید کارگردانان فیلم را ردیابی کنیم و همچنین یک رابطه یک به یک با Movie
برقرار کنیم.
فیلد مرجع را برای تعریف یک رابطه اضافه کنید.
می توانید از دستور @ref
برای سفارشی کردن محدودیت کلید خارجی استفاده کنید.
-
@ref(fields)
برای تعیین فیلدهای کلید خارجی. -
@ref(references)
برای تعیین فیلدهای ارجاع شده در جدول هدف. این مرجع به طور پیش فرض کلید اصلی است، اما فیلدهای با@unique
نیز پشتیبانی می شوند.
برای جزئیات بیشتر، اسناد مرجع برای @ref
را بررسی کنید.
# Movie Metadata
# Movie - MovieMetadata is a one-to-one relationship
type MovieMetadata @table {
# @unique ensures that each Movie only has one MoiveMetadata.
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
}
بازیگر و بازیگر سینما
در مرحله بعد، شما می خواهید بازیگران در فیلم های شما بازی کنند، و از آنجایی که بین فیلم ها و بازیگران رابطه چند به چند دارید، یک جدول پیوستن ایجاد کنید.
# 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
}
کاربر
در نهایت، کاربران برای برنامه شما.
# Users
# Suppose a user can leave reviews for movies
type User @table {
id: String! @default(expr: "auth.uid")
username: String! @col(dataType: "varchar(50)")
}
انواع داده های پشتیبانی شده
Data Connect از انواع داده های اسکالر زیر پشتیبانی می کند، با انتساب به انواع PostgreSQL با استفاده از @col(dataType:)
.
نوع Data Connect | GraphQL توکار نوع یا نوع سفارشی Data Connect | نوع پیش فرض PostgreSQL | پشتیبانی از انواع PostgreSQL (نام مستعار داخل پرانتز) |
---|---|---|---|
رشته | GraphQL | متن | متن بیت (n)، varbit (n) char(n)، varchar(n) |
بین المللی | GraphQL | بین المللی | Int2 (کوچک، سریال کوچک)، int4 (عدد صحیح، int، سریال) |
شناور | GraphQL | شناور8 | float4 (واقعی) float8 (دقت دوگانه) عددی (اعشاری) |
بولی | GraphQL | بولی | بولی |
UUID | سفارشی | uuid | uuid |
Int64 | سفارشی | bigint | int8 (bigint، bigserial) عددی (اعشاری) |
تاریخ | سفارشی | تاریخ | تاریخ |
مهر زمان | سفارشی | timestamptz | timestamptz توجه: اطلاعات منطقه زمانی محلی ذخیره نمی شود. |
بردار | سفارشی | بردار | بردار به انجام جستجوی شباهت برداری با Vertex AI مراجعه کنید. |
- GraphQL
List
به یک آرایه یک بعدی نگاشت می شود.- برای مثال،
[Int]
بهint5[]
,[Any]
بهjsonb[]
نقشه میدهد. - Data Connect از آرایه های تو در تو پشتیبانی نمی کند.
- برای مثال،
کوئری ها و جهش های ضمنی و از پیش تعریف شده
جستارها و جهش های Data Connect شما مجموعه ای از پرس و جوهای ضمنی و جهش های ضمنی ایجاد شده توسط Data Connect را بر اساس انواع و روابط نوع در طرح شما گسترش می دهند. هر زمان که شما طرحواره خود را ویرایش می کنید، پرس و جوها و جهش های ضمنی توسط ابزارهای محلی ایجاد می شوند.
در فرآیند توسعه خود، پرس و جوهای از پیش تعریف شده و جهش های از پیش تعریف شده را بر اساس این عملیات ضمنی پیاده سازی خواهید کرد.
پرس و جو ضمنی و نامگذاری جهش
Data Connect نام های مناسب را برای پرس و جوها و جهش های ضمنی از اعلان های نوع طرحواره شما استنتاج می کند. به عنوان مثال، با کار با یک منبع PostgreSQL، اگر جدولی به نام Movie
تعریف کنید، سرور به صورت ضمنی تولید می کند:
- پرسوجوها برای جدولهای تکی با نامهای دوستانه
movie
(مفرد، برای بازیابی نتایج منفرد با عبور ارگهایی مانندeq
) وmovies
(جمع، برای بازیابی فهرستهای نتایج، ارگهایی مانندgt
و عملیاتی مانندorderby
) استفاده میکنند. Data Connect همچنین پرس و جوهایی را برای عملیات های چند جدولی و رابطه ای با نام های صریح مانندactors_on_movies
یاactors_via_actormovie
ایجاد می کند. - جهش هایی با نام
movie_insert
,movie_upsert
...
زبان تعریف طرحواره همچنین به شما این امکان را می دهد که با استفاده از آرگومان های دستوری singular
و plural
، نام عملیات را به صراحت تنظیم کنید.
دستورالعمل برای پرس و جو و جهش
علاوه بر دستورالعملهایی که در تعریف انواع و جداول استفاده میکنید، Data Connect دستورات @auth
، @check
، @redact
و @transaction
را برای تقویت رفتار کوئریها و جهشها ارائه میکند.
بخشنامه | قابل اجرا برای | توضیحات |
---|---|---|
@auth | پرس و جو و جهش | خط مشی احراز هویت را برای یک پرس و جو یا جهش تعریف می کند. راهنمای مجوز و گواهینامه را ببینید. |
@check | درخواست جستجوی داده های مجوز | بررسی می کند که فیلدهای مشخص شده در نتایج پرس و جو وجود دارد. یک عبارت Common Expression Language (CEL) برای آزمایش مقادیر فیلد استفاده می شود. راهنمای مجوز و گواهینامه را ببینید. |
@redact | پرس و جوها | بخشی از پاسخ مشتری را ویرایش می کند. راهنمای مجوز و گواهینامه را ببینید. |
@transaction | جهش ها | الزام می کند که یک جهش همیشه در یک تراکنش پایگاه داده اجرا شود. نمونه های جهش برنامه فیلم را ببینید. |
پرس و جو برای پایگاه داده نقد و بررسی فیلم
شما یک کوئری Data Connect را با اعلان نوع عملیات پرس و جو، نام عملیات، آرگومان های عملیات صفر یا بیشتر، و صفر یا بیشتر دستورالعمل با آرگومان ها تعریف می کنید.
در شروع سریع، پرس و جوی مثال listEmails
هیچ پارامتری نداشت. البته در بسیاری از موارد داده های ارسال شده به فیلدهای پرس و جو پویا خواهند بود. میتوانید از نحو $variableName
برای کار با متغیرها بهعنوان یکی از اجزای تعریف پرسوجو استفاده کنید.
بنابراین پرس و جو زیر دارد:
- تعریف نوع
query
- نام عملیات
ListMoviesByGenre
(پرس و جو). - یک آرگومان عملیات
$genre
متغییر - یک دستورالعمل واحد،
@auth
.
query ListMoviesByGenre($genre: String!) @auth(level: USER)
هر آرگومان پرس و جو نیاز به یک اعلان نوع، یک نوع داخلی مانند String
، یا یک نوع سفارشی، طرحواره تعریف شده مانند Movie
دارد.
بیایید به امضای پرس و جوهای پیچیده تر نگاه کنیم. شما با معرفی عبارات ارتباطی قدرتمند و مختصر موجود در پرسوجوهای ضمنی که میتوانید در پرسوجوهای از پیش تعریفشده خود بر روی آنها بسازید، به پایان میرسید.
اسکالرهای کلیدی در پرس و جوها
اما ابتدا یک نکته در مورد اسکالرهای کلیدی.
Data Connect نوع خاصی را برای اسکالرهای کلیدی تعریف می کند که با _Key
مشخص می شود. به عنوان مثال، نوع اسکالر کلید برای جدول Movie
ما Movie_Key
است.
شما اسکالرهای کلیدی را به عنوان پاسخی که توسط اکثر جهشهای ضمنی برگردانده میشود، یا البته از کوئریهایی که تمام فیلدهای مورد نیاز برای ساختن کلید اسکالر را بازیابی کردهاید، بازیابی میکنید.
پرسوجوهای خودکار منفرد، مانند movie
در مثال در حال اجرا، از یک آرگومان کلیدی پشتیبانی میکنند که یک اسکالر کلیدی را میپذیرد.
شما ممکن است یک اسکالر کلیدی را به صورت تحت اللفظی پاس کنید. اما، می توانید متغیرهایی را برای ارسال اسکالرهای کلیدی به عنوان ورودی تعریف کنید.
query GetMovie($myKey: Movie_Key!) {
movie(key: $myKey) { title }
}
اینها را می توان در درخواست JSON مانند این (یا سایر قالب های سریال سازی) ارائه کرد:
{
# …
"variables": {
"myKey": {"foo": "some-string-value", "bar": 42}
}
}
به لطف تجزیه اسکالر سفارشی، یک Movie_Key
نیز می تواند با استفاده از نحو شی که ممکن است حاوی متغیرهایی باشد ساخته شود. این بیشتر زمانی مفید است که بخواهید به دلایلی اجزای جداگانه را به متغیرهای مختلف تقسیم کنید.
نام مستعار در پرس و جوها
Data Connect از نام مستعار GraphQL در کوئری ها پشتیبانی می کند. با نام مستعار، نام داده هایی را که در نتایج یک پرس و جو برگردانده می شوند، تغییر می دهید. یک کوئری Data Connect می تواند چندین فیلتر یا عملیات پرس و جوی دیگر را در یک درخواست کارآمد به سرور اعمال کند و به طور موثر چندین «پرس و جوی فرعی» را همزمان صادر کند. برای جلوگیری از تصادم نام در مجموعه داده های برگشتی، از نام مستعار برای تشخیص پرس و جوهای فرعی استفاده می کنید.
در اینجا یک جستجو وجود دارد که در آن یک عبارت از نام مستعار mostPopular
استفاده می کند.
query ReviewTopPopularity($genre: String) {
mostPopular: review(first: {
where: {genre: {eq: $genre}},
orderBy: {popularity: DESC}
}) { … }
}
پرس و جوهای ساده با فیلتر
پرس و جوهای 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
}
}
query MoviesByReleaseYear($min: Int, $max: Int) {
movies(where: {releaseYear: {le: $max, ge: $min}}, orderBy: [{releaseYear: ASC}]) { … }
}
عملگرهای limit
و offset
(پرس و جوهای مفرد، جمع)
می توانید صفحه بندی را روی نتایج انجام دهید. این آرگومانها پذیرفته میشوند اما به نتایج بازگردانده نمیشوند.
query MoviesTop10 {
movies(orderBy: [{ rating: DESC }], limit: 10) {
# graphql: list the fields from the results to return
title
}
}
شامل زمینه های آرایه می شود
می توانید آزمایش کنید که یک فیلد آرایه شامل یک آیتم مشخص شده باشد.
# 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
}
}
عملیات رشته و عبارات منظم
جستارهای شما می توانند از عملیات جستجو و مقایسه رشته ای معمولی از جمله عبارات منظم استفاده کنند. توجه داشته باشید برای کارایی شما چندین عملیات را در اینجا دسته بندی می کنید و آنها را با نام مستعار رفع می کنید.
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}}}) {...}
}
or
و and
برای فیلترهای ترکیبی
or
و and
برای منطق پیچیده تر استفاده کنید.
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 Connect می توانند به داده ها بر اساس روابط بین جداول دسترسی داشته باشند. شما می توانید از روابط شی (یک به یک) یا آرایه (یک به چند) تعریف شده در طرحواره خود برای ایجاد پرس و جوهای تودرتو، یعنی واکشی داده برای یک نوع به همراه داده های یک نوع تودرتو یا مرتبط استفاده کنید.
چنین پرس و جوهایی از جادویی Data Connect _on_
و _via
syntax در جستارهای ضمنی تولید شده استفاده می کنند.
شما تغییراتی در طرحواره از نسخه اولیه ما ایجاد خواهید کرد.
بسیاری به یک
بیایید نظرات را به برنامه خود اضافه کنیم، با جدول Review
و تغییراتی در User
.
# 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")
}
پرس و جو برای خیلی به یک
حالا بیایید به یک پرس و جو نگاه کنیم، با نام مستعار، برای نشان دادن نحو _via_
.
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
}
}
}
یک به یک
می توانید الگو را ببینید. در زیر، این طرح برای تصویر اصلاح شده است.
# 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
}
یک به یک پرس و جو کنید
می توانید با استفاده از نحو _on_
پرس و جو کنید.
# One to one
query GetMovieMetadata($id: UUID!) @auth(level: PUBLIC) {
movie(id: $id) {
movieMetadatas_on_movie {
director
}
}
}
خیلی به خیلی ها
فیلم ها به بازیگر نیاز دارند و بازیگران به فیلم. آنها روابط بسیار زیادی دارند که می توانید با جدول پیوستن MovieActors
مدل کنید.
# 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!]!
}
پرس و جو برای بسیاری از بسیاری
بیایید به یک پرس و جو با نام مستعار نگاه کنیم تا نحو _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 Connect جهش های ضمنی اساسی را برای هر جدول ایجاد می کند.
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!
}
با استفاده از این موارد، می توانید موارد پیچیده هسته ای CRUD را پیاده سازی کنید. پنج بار سریع بگو!
دستورالعمل @transaction
این دستورالعمل الزام می کند که یک جهش همیشه در یک تراکنش پایگاه داده اجرا شود.
جهش با @transaction
تضمین شده است که یا به طور کامل موفق شود یا به طور کامل شکست بخورد. اگر هر یک از فیلدهای داخل تراکنش از کار بیفتد، کل تراکنش برگردانده می شود. از نقطه نظر مشتری، هر شکست به گونه ای رفتار می کند که گویی کل درخواست با یک خطای درخواست شکست خورده است و اجرا آغاز نشده است.
جهش های بدون @transaction
هر فیلد ریشه را یکی پس از دیگری به ترتیب اجرا می کنند. هر گونه خطا را به عنوان خطای میدانی جزئی نشان می دهد، اما تاثیرات اجرای بعدی را نه.
ایجاد کنید
بیایید کارهای اساسی انجام دهیم.
# 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
})
}
یا یک تاپیک
# 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"
})
}
به روز رسانی را انجام دهید
در اینجا به روز رسانی است. تهیهکنندگان و کارگردانان مطمئناً امیدوارند که این رتبهبندیهای متوسط رو به رشد باشد.
mutation UpdateMovie(
$id: UUID!,
$genre: String!,
$rating: Int!,
$description: String!
) {
movie_update(id: $id, data: {
genre: $genre
rating: $rating
description: $description
})
}
# Multiple updates (increase all ratings of a genre)
mutation IncreaseRatingForGenre($genre: String!, $ratingIncrement: Int!) {
movie_updateMany(
where: { genre: { eq: $genre } },
update: { rating: { inc: $ratingIncrement } }
)
}
حذف ها را انجام دهید
البته می توانید داده های فیلم را حذف کنید. محافظان فیلم مطمئناً مایلند که فیلمهای فیزیکی تا زمانی که ممکن است نگهداری شوند.
# Delete by key
mutation DeleteMovie($id: UUID!) {
movie_delete(id: $id)
}
در اینجا می توانید از _deleteMany
استفاده کنید.
# Multiple deletes
mutation DeleteUnpopularMovies($minRating: Int!) {
movie_deleteMany(where: { rating: { le: $minRating } })
}
جهش را روی روابط بنویسید
نحوه استفاده از جهش _upsert
ضمنی را در یک رابطه مشاهده کنید.
# Create or update a one to one relation
mutation MovieMetadataUpsert($movieId: UUID!, $director: String!) {
movieMetadata_upsert(
data: { movie: { id: $movieId }, director: $director }
)
}
درخواست جستجوی داده های مجوز
جهش های Data Connect را می توان با پرس و جو در پایگاه داده و تأیید نتایج پرس و جو با عبارات CEL مجاز کرد. این زمانی مفید است که، برای مثال، در حال نوشتن روی یک جدول هستید، و باید محتویات یک ردیف را در جدول دیگری بررسی کنید.
این ویژگی پشتیبانی می کند:
- دستورالعمل
@check
، که به شما امکان میدهد محتویات فیلدها را ارزیابی کنید و بر اساس نتایج چنین ارزیابی:- ایجاد، به روز رسانی و حذف های تعریف شده توسط یک جهش را ادامه دهید
- برای بازگرداندن نتایج یک پرس و جو ادامه دهید
- از مقادیر برگشتی برای اجرای منطق های مختلف در کد مشتری خود استفاده کنید
- دستورالعمل
@redact
، که به شما امکان می دهد نتایج پرس و جو را از نتایج پروتکل سیمی حذف کنید.
این ویژگی ها برای جریان های مجوز مفید هستند.
طرحواره SQL معادل
-- 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);
بعدش چی؟
- بیاموزید که چگونه پرس و جوها و جهش های خود را با مجوز و گواهی ایمن کنید.
- با نحوه فراخوانی پرسشها و جهشهای خود از یک وب SDK ، Android SDK ، iOS SDK و Flutter SDK که بهطور خودکار ایجاد میشود، بیاموزید.
Firebase Data Connect به شما امکان می دهد برای نمونه های PostgreSQL خود که با Google Cloud SQL مدیریت می شوند، رابط ایجاد کنید. این رابطها ترکیبی از طرحواره، پرسشها و جهشها برای استفاده از دادههای شما هستند.
راهنمای شروع یک طرح برنامه بررسی فیلم را برای PostgreSQL معرفی کرد و این راهنما نگاهی عمیق تر به نحوه طراحی طرحواره های Data Connect برای PostgreSQL دارد.
این راهنما پرس و جوها و جهش های Data Connect را با نمونه های طرحواره جفت می کند. چرا پرس و جوها (و جهش ها ) را در راهنمای طرحواره های Data Connect مورد بحث قرار می دهیم؟ مانند سایر پلتفرمهای مبتنی بر GraphQL، Firebase Data Connect یک پلتفرم توسعه اولین پرس و جو است، بنابراین بهعنوان یک توسعهدهنده، در مدلسازی دادههای خود به دادههایی فکر میکنید که مشتریانتان به آن نیاز دارند، که تا حد زیادی بر طرح دادهای که برای پروژه خود ایجاد میکنید، تأثیر میگذارد.
این راهنما با طرحی جدید برای بررسی فیلم شروع میشود، سپس پرسشها و جهشهای حاصل از آن طرح را پوشش میدهد و در نهایت فهرستی از SQL معادل طرح اصلی Data Connect ارائه میدهد.
طرحی برای یک برنامه بررسی فیلم
تصور کنید می خواهید سرویسی بسازید که به کاربران اجازه می دهد نظرات فیلم ها را ارسال و مشاهده کنند.
برای چنین اپلیکیشنی به یک طرح اولیه نیاز دارید. بعداً این طرح را برای ایجاد پرس و جوهای رابطه ای پیچیده گسترش خواهید داد.
میز فیلم
طرح فیلم ها حاوی دستورالعمل های اصلی مانند:
-
@table(name)
و@col(name)
برای سفارشی کردن جدول SQL و نام ستون. Data Connect نامهای snake_case را در صورت عدم مشخص کردن ایجاد میکند. -
@col(dataType)
برای سفارشی کردن انواع ستون SQL. -
@default
برای پیکربندی مقادیر پیشفرض ستون SQL در حین درج.
برای جزئیات بیشتر، اسناد مرجع برای @table
، @col
، @default
را بررسی کنید.
# 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
}
مقادیر سرور و اسکالرهای کلیدی
قبل از دیدن برنامه بررسی فیلم، اجازه دهید مقادیر سرور Data Connect و اسکالرهای کلیدی را معرفی کنیم.
با استفاده از مقادیر سرور ، می توانید به طور موثری به سرور به صورت پویا در جداول خود با استفاده از مقادیر ذخیره شده یا به راحتی قابل محاسبه با توجه به عبارات خاص سمت سرور جمع کنید. به عنوان مثال ، می توانید در هنگام دسترسی به قسمت با استفاده از عبارت updatedAt: Timestamp! @default(expr: "request.time")
.
مقیاس های کلیدی شناسه های شیء مختصر هستند که داده ها به طور خودکار از قسمت های کلیدی در طرح های شما جمع می شوند. مقیاس های کلیدی در مورد کارآیی هستند و به شما امکان می دهند اطلاعات مربوط به هویت و ساختار داده های خود را در یک تماس یک تماس پیدا کنید. آنها به ویژه هنگامی مفید هستند که می خواهید اقدامات پی در پی روی سوابق جدید انجام دهید و به یک شناسه منحصر به فرد برای انتقال به عملیات آینده نیاز دارید ، و همچنین وقتی می خواهید به کلیدهای رابطه ای دسترسی پیدا کنید تا عملیات پیچیده تری انجام دهید.
میز فوق داده فیلم
حال بیایید کارگردانان فیلم را پیگیری کنیم و همچنین رابطه یک به یک با Movie
برقرار کنیم.
برای تعریف روابط ، قسمت مرجع را اضافه کنید.
می توانید از دستورالعمل @ref
برای شخصی سازی محدودیت کلید خارجی استفاده کنید.
-
@ref(fields)
برای مشخص کردن زمینه های کلید خارجی. -
@ref(references)
برای مشخص کردن زمینه های ذکر شده در جدول هدف. این مرجع به کلید اصلی پیش فرض می شود ، اما زمینه هایی با@unique
نیز پشتیبانی می شوند.
برای اطلاعات بیشتر ، اسناد مرجع را برای @ref
بررسی کنید.
# Movie Metadata
# Movie - MovieMetadata is a one-to-one relationship
type MovieMetadata @table {
# @unique ensures that each Movie only has one MoiveMetadata.
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
}
بازیگر
در مرحله بعد ، شما می خواهید بازیگران در فیلم های خود بازی کنند و از آنجا که شما بین فیلم ها و بازیگران رابطه بسیار زیادی دارید ، یک جدول پیوست ایجاد کنید.
# 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
}
کاربر
در آخر ، کاربران برای برنامه شما.
# Users
# Suppose a user can leave reviews for movies
type User @table {
id: String! @default(expr: "auth.uid")
username: String! @col(dataType: "varchar(50)")
}
انواع داده های پشتیبانی شده
Data Connect از انواع داده های مقیاس زیر پشتیبانی می کند ، با تکالیف به انواع PostgreSQL با استفاده از @col(dataType:)
.
نوع Data Connect | GraphQL نوع داخلی یا Data Connect نوع سفارشی | نوع پیش فرض postgresql | انواع پشتیبانی شده postgresql (نام مستعار در پرانتز) |
---|---|---|---|
رشته | GraphQL | متن | متن بیت (n) ، varbit (n) char (n) ، varchar (n) |
بین المللی | GraphQL | بین المللی | int2 (کوچک ، کوچک) ، int4 (عدد صحیح ، int ، سریال) |
شناور | GraphQL | شناور8 | float4 (واقعی) float8 (دقت دو برابر) عددی (اعشاری) |
بولی | GraphQL | بولی | بولی |
UUID | سفارشی | uuid | uuid |
Int64 | سفارشی | bigint | int8 (bigint ، bigserial) عددی (اعشاری) |
تاریخ | سفارشی | تاریخ | تاریخ |
مهر زمان | سفارشی | timestamptz | timestamptz توجه: اطلاعات محلی منطقه ای ذخیره نمی شود. |
بردار | سفارشی | بردار | بردار به جستجوی شباهت وکتور با Vertex AI مراجعه کنید. |
- نقشه های
List
GraphQL به یک آرایه یک بعدی.- به عنوان مثال ، نقشه های
[Int]
بهint5[]
،[Any]
نقشه بهjsonb[]
. - Data Connect از آرایه های تو در تو پشتیبانی نمی کند.
- به عنوان مثال ، نقشه های
نمایش داده ها و جهش های ضمنی و از پیش تعریف شده
داده ها و جهش های Data Connect شما مجموعه ای از نمایش داده شدگان ضمنی و جهش های ضمنی ایجاد شده توسط Data Connect را بر اساس انواع و روابط نوع موجود در طرح شما گسترش می دهد. نمایش داده ها و جهش های ضمنی هر زمان که طرح خود را ویرایش می کنید توسط ابزار محلی ایجاد می شود.
در فرآیند توسعه خود ، نمایش داده شدگان از پیش تعریف شده و جهش های از پیش تعریف شده را بر اساس این عملیات ضمنی اجرا خواهید کرد.
پرس و جو ضمنی و نامگذاری جهش
Data Connect می کنند. به عنوان مثال ، کار با یک منبع PostgreSQL ، اگر یک جدول به نام Movie
را تعریف کنید ، سرور ضمنی تولید می کند:
- نمایش داده شد برای موارد استفاده از جدول با
movie
نامهای دوستانه (مفرد ، برای بازیابی نتایج فردی که استدلال هایی مانندeq
) وmovies
(جمع آوری ، برای بازیابی لیست های نتیجه مانندgt
و عملیاتی مانندorderby
). Data Connect همچنین برای عملیات چند جدول ، رابطه ای با نامهای صریح مانندactors_on_movies
یاactors_via_actormovie
نمایش داده می شود. - جهش به نام
movie_insert
،movie_upsert
...
زبان تعریف Schema همچنین به شما امکان می دهد تا با استفاده از استدلال های دستورالعمل singular
و plural
به صراحت نامهایی را برای عملیات تنظیم کنید.
بخشنامه هایی برای نمایش داده ها و جهش ها
علاوه بر دستورالعمل هایی که در تعریف انواع و جداول از آنها استفاده می کنید ، Data Connect برای تقویت رفتار نمایش داده ها و جهش ها دستورالعمل های @auth
، @check
، @redact
و @transaction
را ارائه می دهند.
بخشنامه | قابل اجرا برای | توضیحات |
---|---|---|
@auth | نمایش داده ها و جهش ها | سیاست احراز هویت را برای پرس و جو یا جهش تعریف می کند. به راهنمای مجوز و تأیید مراجعه کنید. |
@check | مجوز داده های جستجوی داده ها | تأیید می کند که زمینه های مشخص شده در نتایج پرس و جو وجود دارند. یک بیان زبان بیان مشترک (CEL) برای آزمایش مقادیر میدان استفاده می شود. به راهنمای مجوز و تأیید مراجعه کنید. |
@redact | پرس و جوها | بخشی از پاسخ مشتری را رد می کند. به راهنمای مجوز و تأیید مراجعه کنید. |
@transaction | جهش ها | اعمال می کند که یک جهش همیشه در یک معامله بانک اطلاعاتی اجرا می شود. نمونه های جهش برنامه فیلم را ببینید. |
نمایش داده شد برای بانک اطلاعاتی بررسی فیلم
شما یک پرس و جو Data Connect با بیانیه عملکرد پرس و جو ، نام عملکرد ، آرگومان های صفر یا بیشتر عملیات و دستورالعمل های صفر یا بیشتر با آرگومان تعریف می کنید.
در QuickStart ، مثال Query listEmails
هیچ پارامتری نگرفت. البته در بسیاری موارد ، داده های منتقل شده به زمینه های پرس و جو پویا خواهند بود. برای کار با متغیرها به عنوان یکی از مؤلفه های تعریف پرس و جو می توانید از نحو $variableName
استفاده کنید.
بنابراین پرس و جو زیر:
- تعریف نوع
query
- نام عملیات
ListMoviesByGenre
(پرس و جو) - یک آرگومان عملکرد
$genre
متغیر - یک بخشنامه واحد ،
@auth
.
query ListMoviesByGenre($genre: String!) @auth(level: USER)
هر آرگومان پرس و جو نیاز به یک نوع اعلامیه ، یک رشته داخلی مانند String
یا یک نوع تعریف شده از طرحواره مانند Movie
دارد.
بیایید به امضای نمایش داده های فزاینده پیچیده بپردازیم. شما با معرفی عبارات روابط قدرتمند و مختصر موجود در نمایش داده های ضمنی که می توانید در نمایش داده های از پیش تعریف شده خود ایجاد کنید ، پایان خواهید داد.
مقیاس های کلیدی در نمایش داده شد
اما اول ، یادداشتی در مورد مقیاس های کلیدی.
Data Connect نوع خاصی را برای مقیاس های کلیدی تعریف می کند ، که توسط _Key
مشخص شده است. به عنوان مثال ، نوع یک مقیاس کلیدی برای جدول Movie
ما Movie_Key
است.
شما مقیاس های کلیدی را به عنوان پاسخی که توسط بیشتر جهش های ضمنی بازگردانده می شود ، بازیابی می کنید ، یا البته از پرس و جو در جایی که تمام زمینه های مورد نیاز برای ساخت کلید Scalar را بازیابی کرده اید.
نمایش داده های اتوماتیک مفرد ، مانند movie
در مثال در حال اجرا ، از یک استدلال کلیدی پشتیبانی می کند که یک مقیاس کلیدی را می پذیرد.
ممکن است یک مقیاس کلیدی را به عنوان یک لفظی منتقل کنید. اما ، می توانید متغیرهایی را برای عبور از مقیاس های کلیدی به عنوان ورودی تعریف کنید.
query GetMovie($myKey: Movie_Key!) {
movie(key: $myKey) { title }
}
این موارد را می توان در درخواست JSON مانند این (یا سایر قالب های سریال سازی) ارائه داد:
{
# …
"variables": {
"myKey": {"foo": "some-string-value", "bar": 42}
}
}
به لطف تجزیه مقیاس سفارشی ، یک Movie_Key
نیز می تواند با استفاده از نحو شیء ساخته شود ، که ممکن است حاوی متغیرها باشد. این بیشتر زمانی مفید است که به دلایلی می خواهید اجزای فردی را به متغیرهای مختلف تقسیم کنید.
در نمایش داده شد
Data Connect از Graphql در نمایش داده شدگان پشتیبانی می کند. با نام مستعار ، داده هایی را که در نتایج پرس و جو بازگردانده می شوند ، تغییر نام دهید. یک پرس و جو Data Connect واحد می تواند چندین فیلتر یا سایر عملیات پرس و جو را در یک درخواست کارآمد به سرور اعمال کند و به طور موثری چندین "زیرنویس" را به طور همزمان صادر کند. برای جلوگیری از برخورد نام در مجموعه داده های برگشتی ، از نام مستعار برای تمایز زیرمجموعه ها استفاده می کنید.
در اینجا یک پرس و جو وجود دارد که در آن یک عبارت از alias mostPopular
استفاده می کند.
query ReviewTopPopularity($genre: String) {
mostPopular: review(first: {
where: {genre: {eq: $genre}},
orderBy: {popularity: DESC}
}) { … }
}
نمایش داده شدگان ساده با فیلترها
نقشه نمایش داده های 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
}
}
query MoviesByReleaseYear($min: Int, $max: Int) {
movies(where: {releaseYear: {le: $max, ge: $min}}, orderBy: [{releaseYear: ASC}]) { … }
}
اپراتورهای limit
و offset
(نمایش داده های مفرد ، جمع)
شما می توانید در نتایج پیج را انجام دهید. این استدلال ها پذیرفته می شوند اما در نتایج بازگردانده نمی شوند.
query MoviesTop10 {
movies(orderBy: [{ rating: DESC }], limit: 10) {
# graphql: list the fields from the results to return
title
}
}
شامل زمینه های آرایه
می توانید آزمایش کنید که یک قسمت آرایه شامل یک مورد مشخص است.
# 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
}
}
عملیات رشته ای و عبارات منظم
نمایش داده شدگان شما می توانند از عملیات جستجوی رشته ای و مقایسه معمولی ، از جمله عبارات منظم استفاده کنند. توجه داشته باشید برای کارآیی شما چندین عملیات را در اینجا انجام می دهید و آنها را با نام مستعار تفکیک می کنید.
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}}}) {...}
}
or
and
برای فیلترهای تشکیل شده
برای منطق پیچیده تر استفاده کنید or
و و و و و و و و و و و و و و و و و و و و و و و و و و و و و و و and
آنها را.
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 Connect می توانند بر اساس روابط بین جداول به داده ها دسترسی پیدا کنند. شما می توانید از روابط شی (یک به یک) یا آرایه (یک به یک) تعریف شده در طرح خود برای ایجاد نمایش داده های تو در تو استفاده کنید ، یعنی داده ها را برای یک نوع به همراه داده های یک نوع توخالی یا مرتبط.
چنین نمایش داده شدی Data Connect _on_
و _via
Syntax در نمایش داده های ضمنی تولید شده استفاده می کنند.
شما از نسخه اولیه ما تغییراتی در طرحواره ایجاد خواهید کرد.
بسیاری به یک
بیایید با یک جدول Review
و اصلاحات در User
، بررسی ها را به برنامه خود اضافه کنیم.
# 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")
}
پرس و جو برای بسیاری به یکی
حال بیایید به یک پرس و جو بپردازیم ، با بی حس کردن ، syntax _via_
را نشان دهیم.
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
}
}
}
یک به یک
می توانید الگو را ببینید. در زیر ، این طرح برای تصویر اصلاح شده است.
# 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
}
پرس و جو برای یک به یک
می توانید با استفاده از نحو _on_
پرس و جو کنید.
# One to one
query GetMovieMetadata($id: UUID!) @auth(level: PUBLIC) {
movie(id: $id) {
movieMetadatas_on_movie {
director
}
}
}
خیلی به خیلی ها
فیلم ها به بازیگران احتیاج دارند و بازیگران به فیلم احتیاج دارند. آنها رابطه بسیاری دارند که می توانید با جدول پیوستن به MovieActors
مدل کنید.
# 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!]!
}
پرس و جو برای بسیاری از افراد
بیایید به یک پرس و جو بپردازیم ، با بی حس کردن ، برای نشان دادن نحو _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 Connect جهش های ضمنی اساسی برای هر جدول ایجاد می کنند.
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!
}
با این کار ، می توانید موارد Crud Crud را به طور فزاینده ای پیچیده اجرا کنید. بگویید که پنج بار سریع!
دستورالعمل @transaction
این دستورالعمل باعث می شود که یک جهش همیشه در یک معامله پایگاه داده اجرا شود.
جهش با @transaction
تضمین می شود که به طور کامل موفق شود یا به طور کامل شکست بخورد. در صورت عدم موفقیت هر یک از قسمتهای معامله ، کل معامله به عقب برگردانده می شود. از دیدگاه مشتری ، هرگونه شکست طوری رفتار می کند که گویی کل درخواست با خطای درخواست انجام نشده است و اجرای آن آغاز نشده است.
جهش بدون @transaction
هر قسمت ریشه را یکی پس از دیگری به ترتیب انجام می دهد. این خطاها را به عنوان خطاهای میدانی جزئی خط می کند ، اما تأثیرات اعدام های بعدی نیست.
ایجاد کنید
بیایید ایجاد اساسی انجام دهیم.
# 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
})
}
یا یک صعود
# 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"
})
}
به روزرسانی ها را انجام دهید
در اینجا به روزرسانی ها آورده شده است. تولید کنندگان و کارگردانان مطمئناً امیدوارند که این رتبه بندی های متوسط در روند باشد.
mutation UpdateMovie(
$id: UUID!,
$genre: String!,
$rating: Int!,
$description: String!
) {
movie_update(id: $id, data: {
genre: $genre
rating: $rating
description: $description
})
}
# Multiple updates (increase all ratings of a genre)
mutation IncreaseRatingForGenre($genre: String!, $ratingIncrement: Int!) {
movie_updateMany(
where: { genre: { eq: $genre } },
update: { rating: { inc: $ratingIncrement } }
)
}
انجام حذف
مطمئناً می توانید داده های فیلم را حذف کنید. محافظه کاران فیلم مطمئناً می خواهند فیلم های فیزیکی تا حد امکان حفظ شوند.
# Delete by key
mutation DeleteMovie($id: UUID!) {
movie_delete(id: $id)
}
در اینجا می توانید از _deleteMany
استفاده کنید.
# Multiple deletes
mutation DeleteUnpopularMovies($minRating: Int!) {
movie_deleteMany(where: { rating: { le: $minRating } })
}
جهش در مورد روابط بنویسید
نحوه استفاده از جهش ضمنی _upsert
را در رابطه مشاهده کنید.
# Create or update a one to one relation
mutation MovieMetadataUpsert($movieId: UUID!, $director: String!) {
movieMetadata_upsert(
data: { movie: { id: $movieId }, director: $director }
)
}
مجوز داده های جستجوی داده ها
جهش های Data Connect می توانند با پرس و جو اولین پایگاه داده و تأیید نتایج پرس و جو با عبارات CEL مجاز باشند. این زمانی مفید است که به عنوان مثال ، شما در یک جدول می نویسید و باید محتوای یک ردیف را در یک جدول دیگر بررسی کنید.
این ویژگی پشتیبانی می کند:
- دستورالعمل
@check
، که به شما امکان می دهد محتوای زمینه ها را ارزیابی کنید و بر اساس نتایج چنین ارزیابی:- با ایجاد ، به روزرسانی و حذف تعریف شده توسط یک جهش ادامه دهید
- برای بازگشت نتایج یک پرس و جو ادامه دهید
- از مقادیر برگشتی برای انجام منطق مختلف در کد مشتری خود استفاده کنید
- بخشنامه
@redact
، که به شما امکان می دهد نتایج پرس و جو را از نتایج پروتکل سیم حذف کنید.
این ویژگی ها برای جریان مجوز مفید هستند.
طرحواره SQL معادل
-- 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);
بعدش چی؟
- بیاموزید که چگونه می توانید سؤالات و جهش های خود را با مجوز و تأیید ایمن کنید.
- بیاموزید که چگونه می توانید با نمایش داده ها و جهش های خود را از وب سایت SDK ، Android SDK ، iOS SDK و Flutter SDK به صورت خودکار فراخوانی کنید.
Firebase Data Connect به شما امکان می دهد اتصالات را برای نمونه های PostgreSQL خود که با Google Cloud SQL مدیریت شده است ، ایجاد کنید. این اتصالات ترکیبی از یک طرحواره ، نمایش داده شد و جهش برای استفاده از داده های شما هستند.
راهنمای Get Start یک طرح برنامه بررسی فیلم را برای PostgreSQL معرفی کرد ، و این راهنما نگاهی عمیق تر به نحوه طراحی طرح های Data Connect برای PostgreSQL می اندازد.
این راهنما Data Connect . چرا در یک راهنمای درباره طرح های Data Connect در مورد نمایش داده ها (و جهش ها ) بحث می کنیم؟ مانند سایر سیستم عامل های مبتنی بر GraphQL ، Firebase Data Connect یک پلت فرم توسعه پرس و جو است ، بنابراین به عنوان یک توسعه دهنده ، در مدل سازی داده های خود به فکر داده های مشتری خود خواهید بود ، که تا حد زیادی بر طرح داده ای که برای پروژه خود ایجاد می کنید تأثیر خواهد گذاشت.
این راهنما با یک طرح جدید برای بررسی فیلم شروع می شود ، سپس نمایش داده ها و جهش های حاصل از آن طرحواره را پوشش می دهد ، و در آخر یک لیست SQL معادل طرح Core Data Connect Schema را ارائه می دهد.
طرح برای یک برنامه بررسی فیلم
تصور کنید می خواهید خدماتی بسازید که به کاربران امکان ارسال و مشاهده بررسی فیلم ها را می دهد.
برای چنین برنامه ای به یک طرح اولیه نیاز دارید. شما بعداً این طرح را گسترش خواهید داد تا نمایش داده شدگان رابطه ای پیچیده ایجاد شود.
میز فیلم
طرحواره برای فیلم ها شامل دستورالعمل های اصلی مانند:
-
@table(name)
و@col(name)
برای سفارشی کردن جدول و نام ستون SQL. Data Connect در صورت عدم مشخص شدن ، نام Snake_case را تولید می کند. -
@col(dataType)
برای سفارشی کردن انواع ستون SQL. -
@default
برای پیکربندی مقادیر پیش فرض ستون SQL در هنگام درج.
برای اطلاعات بیشتر ، اسناد مرجع را برای @table
، @col
، @default
بررسی کنید.
# 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
}
مقادیر سرور و مقیاس های کلیدی
قبل از دیدن برنامه بررسی فیلم ، بیایید مقادیر سرور Data Connect و مقیاس های کلیدی را معرفی کنیم.
با استفاده از مقادیر سرور ، می توانید به طور موثری به سرور به صورت پویا در جداول خود با استفاده از مقادیر ذخیره شده یا به راحتی قابل محاسبه با توجه به عبارات خاص سمت سرور جمع کنید. به عنوان مثال ، می توانید در هنگام دسترسی به قسمت با استفاده از عبارت updatedAt: Timestamp! @default(expr: "request.time")
.
مقیاس های کلیدی شناسه های شیء مختصر هستند که داده ها به طور خودکار از قسمت های کلیدی در طرح های شما جمع می شوند. مقیاس های کلیدی در مورد کارآیی هستند و به شما امکان می دهند اطلاعات مربوط به هویت و ساختار داده های خود را در یک تماس یک تماس پیدا کنید. آنها به ویژه هنگامی مفید هستند که می خواهید اقدامات پی در پی روی سوابق جدید انجام دهید و به یک شناسه منحصر به فرد برای انتقال به عملیات آینده نیاز دارید ، و همچنین وقتی می خواهید به کلیدهای رابطه ای دسترسی پیدا کنید تا عملیات پیچیده تری انجام دهید.
میز فوق داده فیلم
حال بیایید کارگردانان فیلم را پیگیری کنیم و همچنین رابطه یک به یک با Movie
برقرار کنیم.
برای تعریف روابط ، قسمت مرجع را اضافه کنید.
می توانید از دستورالعمل @ref
برای شخصی سازی محدودیت کلید خارجی استفاده کنید.
-
@ref(fields)
برای مشخص کردن زمینه های کلید خارجی. -
@ref(references)
برای مشخص کردن زمینه های ذکر شده در جدول هدف. این مرجع به کلید اصلی پیش فرض می شود ، اما زمینه هایی با@unique
نیز پشتیبانی می شوند.
برای اطلاعات بیشتر ، اسناد مرجع را برای @ref
بررسی کنید.
# Movie Metadata
# Movie - MovieMetadata is a one-to-one relationship
type MovieMetadata @table {
# @unique ensures that each Movie only has one MoiveMetadata.
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
}
بازیگر
در مرحله بعد ، شما می خواهید بازیگران در فیلم های خود بازی کنند و از آنجا که شما بین فیلم ها و بازیگران رابطه بسیار زیادی دارید ، یک جدول پیوست ایجاد کنید.
# 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
}
کاربر
در آخر ، کاربران برای برنامه شما.
# Users
# Suppose a user can leave reviews for movies
type User @table {
id: String! @default(expr: "auth.uid")
username: String! @col(dataType: "varchar(50)")
}
انواع داده های پشتیبانی شده
Data Connect از انواع داده های مقیاس زیر پشتیبانی می کند ، با تکالیف به انواع PostgreSQL با استفاده از @col(dataType:)
.
نوع Data Connect | GraphQL نوع داخلی یا Data Connect نوع سفارشی | نوع پیش فرض postgresql | انواع پشتیبانی شده postgresql (نام مستعار در پرانتز) |
---|---|---|---|
رشته | GraphQL | متن | متن بیت (n) ، varbit (n) char (n) ، varchar (n) |
بین المللی | GraphQL | بین المللی | int2 (کوچک ، کوچک) ، int4 (عدد صحیح ، int ، سریال) |
شناور | GraphQL | شناور8 | float4 (واقعی) float8 (دقت دو برابر) عددی (اعشاری) |
بولی | GraphQL | بولی | بولی |
UUID | سفارشی | uuid | uuid |
Int64 | سفارشی | bigint | int8 (bigint ، bigserial) عددی (اعشاری) |
تاریخ | سفارشی | تاریخ | تاریخ |
مهر زمان | سفارشی | timestamptz | timestamptz توجه: اطلاعات محلی منطقه ای ذخیره نمی شود. |
بردار | سفارشی | بردار | بردار به جستجوی شباهت وکتور با Vertex AI مراجعه کنید. |
- نقشه های
List
GraphQL به یک آرایه یک بعدی.- به عنوان مثال ، نقشه های
[Int]
بهint5[]
،[Any]
نقشه بهjsonb[]
. - Data Connect از آرایه های تو در تو پشتیبانی نمی کند.
- به عنوان مثال ، نقشه های
نمایش داده ها و جهش های ضمنی و از پیش تعریف شده
داده ها و جهش های Data Connect شما مجموعه ای از نمایش داده شدگان ضمنی و جهش های ضمنی ایجاد شده توسط Data Connect را بر اساس انواع و روابط نوع موجود در طرح شما گسترش می دهد. نمایش داده ها و جهش های ضمنی هر زمان که طرح خود را ویرایش می کنید توسط ابزار محلی ایجاد می شود.
در فرآیند توسعه خود ، نمایش داده شدگان از پیش تعریف شده و جهش های از پیش تعریف شده را بر اساس این عملیات ضمنی اجرا خواهید کرد.
پرس و جو ضمنی و نامگذاری جهش
Data Connect می کنند. به عنوان مثال ، کار با یک منبع PostgreSQL ، اگر یک جدول به نام Movie
را تعریف کنید ، سرور ضمنی تولید می کند:
- نمایش داده شد برای موارد استفاده از جدول با
movie
نامهای دوستانه (مفرد ، برای بازیابی نتایج فردی که استدلال هایی مانندeq
) وmovies
(جمع آوری ، برای بازیابی لیست های نتیجه مانندgt
و عملیاتی مانندorderby
). Data Connect همچنین برای عملیات چند جدول ، رابطه ای با نامهای صریح مانندactors_on_movies
یاactors_via_actormovie
نمایش داده می شود. - جهش به نام
movie_insert
،movie_upsert
...
زبان تعریف Schema همچنین به شما امکان می دهد تا با استفاده از استدلال های دستورالعمل singular
و plural
به صراحت نامهایی را برای عملیات تنظیم کنید.
بخشنامه هایی برای نمایش داده ها و جهش ها
علاوه بر دستورالعمل هایی که در تعریف انواع و جداول از آنها استفاده می کنید ، Data Connect برای تقویت رفتار نمایش داده ها و جهش ها دستورالعمل های @auth
، @check
، @redact
و @transaction
را ارائه می دهند.
بخشنامه | قابل اجرا برای | توضیحات |
---|---|---|
@auth | نمایش داده ها و جهش ها | سیاست احراز هویت را برای پرس و جو یا جهش تعریف می کند. به راهنمای مجوز و تأیید مراجعه کنید. |
@check | مجوز داده های جستجوی داده ها | تأیید می کند که زمینه های مشخص شده در نتایج پرس و جو وجود دارند. یک بیان زبان بیان مشترک (CEL) برای آزمایش مقادیر میدان استفاده می شود. به راهنمای مجوز و تأیید مراجعه کنید. |
@redact | پرس و جوها | بخشی از پاسخ مشتری را رد می کند. به راهنمای مجوز و تأیید مراجعه کنید. |
@transaction | جهش ها | اعمال می کند که یک جهش همیشه در یک معامله بانک اطلاعاتی اجرا می شود. نمونه های جهش برنامه فیلم را ببینید. |
نمایش داده شد برای بانک اطلاعاتی بررسی فیلم
شما یک پرس و جو Data Connect با بیانیه عملکرد پرس و جو ، نام عملکرد ، آرگومان های صفر یا بیشتر عملیات و دستورالعمل های صفر یا بیشتر با آرگومان تعریف می کنید.
در QuickStart ، مثال Query listEmails
هیچ پارامتری نگرفت. البته در بسیاری موارد ، داده های منتقل شده به زمینه های پرس و جو پویا خواهند بود. برای کار با متغیرها به عنوان یکی از مؤلفه های تعریف پرس و جو می توانید از نحو $variableName
استفاده کنید.
بنابراین پرس و جو زیر:
- تعریف نوع
query
- نام عملیات
ListMoviesByGenre
(پرس و جو) - یک آرگومان عملکرد
$genre
متغیر - یک بخشنامه واحد ،
@auth
.
query ListMoviesByGenre($genre: String!) @auth(level: USER)
هر آرگومان پرس و جو نیاز به یک نوع اعلامیه ، یک رشته داخلی مانند String
یا یک نوع تعریف شده از طرحواره مانند Movie
دارد.
بیایید به امضای نمایش داده های فزاینده پیچیده بپردازیم. شما با معرفی عبارات روابط قدرتمند و مختصر موجود در نمایش داده های ضمنی که می توانید در نمایش داده های از پیش تعریف شده خود ایجاد کنید ، پایان خواهید داد.
مقیاس های کلیدی در نمایش داده شد
اما اول ، یادداشتی در مورد مقیاس های کلیدی.
Data Connect نوع خاصی را برای مقیاس های کلیدی تعریف می کند ، که توسط _Key
مشخص شده است. به عنوان مثال ، نوع یک مقیاس کلیدی برای جدول Movie
ما Movie_Key
است.
شما مقیاس های کلیدی را به عنوان پاسخی که توسط بیشتر جهش های ضمنی بازگردانده می شود ، بازیابی می کنید ، یا البته از پرس و جو در جایی که تمام زمینه های مورد نیاز برای ساخت کلید Scalar را بازیابی کرده اید.
نمایش داده های اتوماتیک مفرد ، مانند movie
در مثال در حال اجرا ، از یک استدلال کلیدی پشتیبانی می کند که یک مقیاس کلیدی را می پذیرد.
ممکن است یک مقیاس کلیدی را به عنوان یک لفظی منتقل کنید. اما ، می توانید متغیرهایی را برای عبور از مقیاس های کلیدی به عنوان ورودی تعریف کنید.
query GetMovie($myKey: Movie_Key!) {
movie(key: $myKey) { title }
}
این موارد را می توان در درخواست JSON مانند این (یا سایر قالب های سریال سازی) ارائه داد:
{
# …
"variables": {
"myKey": {"foo": "some-string-value", "bar": 42}
}
}
به لطف تجزیه مقیاس سفارشی ، یک Movie_Key
نیز می تواند با استفاده از نحو شیء ساخته شود ، که ممکن است حاوی متغیرها باشد. این بیشتر زمانی مفید است که به دلایلی می خواهید اجزای فردی را به متغیرهای مختلف تقسیم کنید.
در نمایش داده شد
Data Connect از Graphql در نمایش داده شدگان پشتیبانی می کند. با نام مستعار ، داده هایی را که در نتایج پرس و جو بازگردانده می شوند ، تغییر نام دهید. یک پرس و جو Data Connect واحد می تواند چندین فیلتر یا سایر عملیات پرس و جو را در یک درخواست کارآمد به سرور اعمال کند و به طور موثری چندین "زیرنویس" را به طور همزمان صادر کند. برای جلوگیری از برخورد نام در مجموعه داده های برگشتی ، از نام مستعار برای تمایز زیرمجموعه ها استفاده می کنید.
در اینجا یک پرس و جو وجود دارد که در آن یک عبارت از alias mostPopular
استفاده می کند.
query ReviewTopPopularity($genre: String) {
mostPopular: review(first: {
where: {genre: {eq: $genre}},
orderBy: {popularity: DESC}
}) { … }
}
نمایش داده شدگان ساده با فیلترها
نقشه نمایش داده های 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
}
}
query MoviesByReleaseYear($min: Int, $max: Int) {
movies(where: {releaseYear: {le: $max, ge: $min}}, orderBy: [{releaseYear: ASC}]) { … }
}
اپراتورهای limit
و offset
(نمایش داده های مفرد ، جمع)
شما می توانید در نتایج پیج را انجام دهید. این استدلال ها پذیرفته می شوند اما در نتایج بازگردانده نمی شوند.
query MoviesTop10 {
movies(orderBy: [{ rating: DESC }], limit: 10) {
# graphql: list the fields from the results to return
title
}
}
شامل زمینه های آرایه
می توانید آزمایش کنید که یک قسمت آرایه شامل یک مورد مشخص است.
# 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
}
}
عملیات رشته ای و عبارات منظم
نمایش داده شدگان شما می توانند از عملیات جستجوی رشته ای و مقایسه معمولی ، از جمله عبارات منظم استفاده کنند. توجه داشته باشید برای کارآیی شما چندین عملیات را در اینجا انجام می دهید و آنها را با نام مستعار تفکیک می کنید.
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}}}) {...}
}
or
and
برای فیلترهای تشکیل شده
برای منطق پیچیده تر استفاده کنید or
و و و و و و و و و و و و و و و و و و و و و و و و و و و و و و و and
آنها را.
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 Connect می توانند بر اساس روابط بین جداول به داده ها دسترسی پیدا کنند. شما می توانید از روابط شی (یک به یک) یا آرایه (یک به یک) تعریف شده در طرح خود برای ایجاد نمایش داده های تو در تو استفاده کنید ، یعنی داده ها را برای یک نوع به همراه داده های یک نوع توخالی یا مرتبط.
چنین نمایش داده شدی Data Connect _on_
و _via
Syntax در نمایش داده های ضمنی تولید شده استفاده می کنند.
شما از نسخه اولیه ما تغییراتی در طرحواره ایجاد خواهید کرد.
بسیاری به یک
بیایید با یک جدول Review
و اصلاحات در User
، بررسی ها را به برنامه خود اضافه کنیم.
# 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")
}
پرس و جو برای بسیاری به یکی
حال بیایید به یک پرس و جو بپردازیم ، با بی حس کردن ، syntax _via_
را نشان دهیم.
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
}
}
}
یک به یک
می توانید الگو را ببینید. در زیر ، این طرح برای تصویر اصلاح شده است.
# 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
}
پرس و جو برای یک به یک
می توانید با استفاده از نحو _on_
پرس و جو کنید.
# One to one
query GetMovieMetadata($id: UUID!) @auth(level: PUBLIC) {
movie(id: $id) {
movieMetadatas_on_movie {
director
}
}
}
خیلی به خیلی ها
فیلم ها به بازیگران احتیاج دارند و بازیگران به فیلم احتیاج دارند. آنها رابطه بسیاری دارند که می توانید با جدول پیوستن به MovieActors
مدل کنید.
# 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!]!
}
پرس و جو برای بسیاری از افراد
بیایید به یک پرس و جو بپردازیم ، با بی حس کردن ، برای نشان دادن نحو _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 Connect جهش های ضمنی اساسی برای هر جدول ایجاد می کنند.
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!
}
با این کار ، می توانید موارد Crud Crud را به طور فزاینده ای پیچیده اجرا کنید. بگویید که پنج بار سریع!
دستورالعمل @transaction
این دستورالعمل باعث می شود که یک جهش همیشه در یک معامله پایگاه داده اجرا شود.
جهش با @transaction
تضمین می شود که به طور کامل موفق شود یا به طور کامل شکست بخورد. در صورت عدم موفقیت هر یک از قسمتهای معامله ، کل معامله به عقب برگردانده می شود. از دیدگاه مشتری ، هرگونه شکست طوری رفتار می کند که گویی کل درخواست با خطای درخواست انجام نشده است و اجرای آن آغاز نشده است.
جهش بدون @transaction
هر قسمت ریشه را یکی پس از دیگری به ترتیب انجام می دهد. این خطاها را به عنوان خطاهای میدانی جزئی خط می کند ، اما تأثیرات اعدام های بعدی نیست.
ایجاد کنید
بیایید ایجاد اساسی انجام دهیم.
# 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
})
}
یا یک صعود
# 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"
})
}
به روزرسانی ها را انجام دهید
در اینجا به روزرسانی ها آورده شده است. تولید کنندگان و کارگردانان مطمئناً امیدوارند که این رتبه بندی های متوسط در روند باشد.
mutation UpdateMovie(
$id: UUID!,
$genre: String!,
$rating: Int!,
$description: String!
) {
movie_update(id: $id, data: {
genre: $genre
rating: $rating
description: $description
})
}
# Multiple updates (increase all ratings of a genre)
mutation IncreaseRatingForGenre($genre: String!, $ratingIncrement: Int!) {
movie_updateMany(
where: { genre: { eq: $genre } },
update: { rating: { inc: $ratingIncrement } }
)
}
انجام حذف
مطمئناً می توانید داده های فیلم را حذف کنید. محافظه کاران فیلم مطمئناً می خواهند فیلم های فیزیکی تا حد امکان حفظ شوند.
# Delete by key
mutation DeleteMovie($id: UUID!) {
movie_delete(id: $id)
}
در اینجا می توانید از _deleteMany
استفاده کنید.
# Multiple deletes
mutation DeleteUnpopularMovies($minRating: Int!) {
movie_deleteMany(where: { rating: { le: $minRating } })
}
جهش در مورد روابط بنویسید
نحوه استفاده از جهش ضمنی _upsert
را در رابطه مشاهده کنید.
# Create or update a one to one relation
mutation MovieMetadataUpsert($movieId: UUID!, $director: String!) {
movieMetadata_upsert(
data: { movie: { id: $movieId }, director: $director }
)
}
مجوز داده های جستجوی داده ها
جهش های Data Connect می توانند با پرس و جو اولین پایگاه داده و تأیید نتایج پرس و جو با عبارات CEL مجاز باشند. این زمانی مفید است که به عنوان مثال ، شما در یک جدول می نویسید و باید محتوای یک ردیف را در یک جدول دیگر بررسی کنید.
این ویژگی پشتیبانی می کند:
- دستورالعمل
@check
، که به شما امکان می دهد محتوای زمینه ها را ارزیابی کنید و بر اساس نتایج چنین ارزیابی:- با ایجاد ، به روزرسانی و حذف تعریف شده توسط یک جهش ادامه دهید
- برای بازگشت نتایج یک پرس و جو ادامه دهید
- از مقادیر برگشتی برای انجام منطق مختلف در کد مشتری خود استفاده کنید
- بخشنامه
@redact
، که به شما امکان می دهد نتایج پرس و جو را از نتایج پروتکل سیم حذف کنید.
این ویژگی ها برای جریان مجوز مفید هستند.
طرحواره SQL معادل
-- 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);
بعدش چی؟
- بیاموزید که چگونه می توانید سؤالات و جهش های خود را با مجوز و تأیید ایمن کنید.
- بیاموزید که چگونه می توانید با نمایش داده ها و جهش های خود را از وب سایت SDK ، Android SDK ، iOS SDK و Flutter SDK به صورت خودکار فراخوانی کنید.