Firebase Data Connect يتيح لك إنشاء أدوات ربط لمثيل PostgreSQL المُدار باستخدام Google Cloud SQL. هذه الوصلات هي مجموعات من مخطّط وطلبات بحث وعمليات تحويل لاستخدام بياناتك.
قدّم دليل البدء مخطّط قاعدة بيانات تطبيق مراجعات الأفلام في PostgreSQL، ويتناول هذا الدليل بالتفصيل كيفية تصميم مخطّطات Data Connect لقاعدة بيانات PostgreSQL.
يجمع هذا الدليل بين Data Connect طلبات البحث والطفرات مع نماذج المخطط. لماذا نناقش طلبات البحث (وعمليات التحويل) في دليل عن Data Connect المخططات؟ مثل المنصات الأخرى المستندة إلى GraphQL، Firebase Data Connect هي منصة تطوير تركز على طلبات البحث، لذا بصفتك أحد المطوّرين، عليك التفكير في البيانات التي يحتاجها العميل عند وضع نماذج للبيانات، ما سيؤثّر بشكل كبير في مخطّط البيانات الذي تُطوّره لمشروعك.
يبدأ هذا الدليل بمخطّط جديد لمراجعات الأفلام، ثم يتناول الاستعلامات والطفرات المشتقة من هذا المخطّط، ويقدّم أخيرًا قائمة SQL مكافئة للمخطّط الأساسي Data Connect.
مخطّط تطبيق لمراجعة الأفلام
لنفترض أنّك تريد إنشاء خدمة تتيح للمستخدمين إرسال مراجعات الأفلام والاطّلاع عليها.
تحتاج إلى مخطّط أولي لتطبيق كهذا. ويمكنك توسيع هذا المخطّط لاحقًا لإنشاء طلبات بحث علاقاتية معقّدة.
جدول الأفلام
يحتوي مخطّط الأفلام على توجيهات أساسية، مثل:
@table
، التي تسمح لنا بضبط أسماء العمليات باستخدام وسيطاتsingular
وplural
@col
لضبط أسماء الأعمدة بشكل صريح@default
للسماح بضبط الإعدادات التلقائية.
# 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")
}
قيم الخادم والمتغيّرات السلعية الرئيسية
قبل الاطّلاع على تطبيق مراجعة الأفلام، لنلقِ نظرة على Data Connect قيم الخادم والمقاييس الرئيسية.
باستخدام قيم الخادم، يمكنك السماح للخادم بتعبئة
الحقول في الجداول بشكل ديناميكي باستخدام قيم مخزّنة أو قابلة للحساب بسهولة وفقًا
لتعبيرات معيّنة من جهة الخادم. على سبيل المثال، يمكنك تحديد حقل تم تطبيق علامة زمنية عليه عند الوصول إلى الحقل باستخدام التعبير
updatedAt: Timestamp! @default(expr: "request.time")
.
المقاييس الرئيسية هي معرّفات مختصرة للكائنات تجمعها أداة Data Connect تلقائيًا من الحقول الرئيسية في مخطّطاتك. تعتمد المقاييس الأساسية على الكفاءة، مما يتيح لك العثور في طلب واحد على معلومات عن هوية بياناتك وبنيتها. وتُعد مفيدة بشكل خاص عندما تريد تنفيذ إجراءات تسلسلية على السجلّات الجديدة وتحتاج إلى معرّف فريد لنقله إلى العمليات القادمة، وكذلك عندما تريد الوصول إلى المفاتيح المتعلّقة بهدف تنفيذ عمليات إضافية أكثر تعقيدًا.
جدول البيانات الوصفية للفيلم
لنتتبّع الآن مخرجي الأفلام، وننشئ أيضًا علاقة شخصية
مع Movie
.
أضِف التوجيه @ref
لتحديد العلاقات.
# 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")
}
Actor وMovieActor
بعد ذلك، تريد أن يشارك ممثلون في أفلامك، وبما أنّ لديك علاقة بين الأفلام والممثلين تتعلّق بالعديد من القيم لكلّ منهما، عليك إنشاء جدول ربط.
# 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(name: "Actors", singular: "actor", plural: "actors") {
id: UUID! @col(name: "actor_id") @default(expr: "uuidV4()")
name: String! @col(name: "name", dataType: "varchar(30)")
}
# Join table for many-to-many relationship for movies and actors
# The 'key' param signifies the primary key(s) of this table
# In this case, the keys are [movieId, actorId], the generated fields of the reference types [movie, actor]
type MovieActor @table(key: ["movie", "actor"]) {
# @ref creates a field in the current table (MovieActor) 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, see: implicit.gql
actor: Actor! @ref
# actorId: UUID! <- this is created by the above @ref, see: implicit.gql
role: String! @col(name: "role") # "main" or "supporting"
# optional other fields
}
المستخدم
أخيرًا، المستخدمون الذين يستخدمون تطبيقك.
# Users
# Suppose a user can leave reviews for movies
# user:reviews is a one to many relationship, movie:reviews is a one to many relationship, movie:user is a many to many relationship
type User
@table(name: "Users", singular: "user", plural: "users", key: ["id"]) {
id: UUID! @col(name: "user_id") @default(expr: "uuidV4()")
auth: String @col(name: "user_auth") @default(expr: "auth.uid")
username: String! @col(name: "username", dataType: "varchar(30)")
# The following are generated from the @ref in the Review table
# reviews_on_user
# movies_via_Review
}
أنواع البيانات المتوافقة
يتيح Data Connect أنواع البيانات السلاسل التالية، مع
عمليات الربط بأنواع PostgreSQL باستخدام @col(dataType:)
.
نوع Data Connect | نوع مضمّن في GraphQL أو Data Connect نوع مخصّص |
نوع PostgreSQL التلقائي | أنواع PostgreSQL المتوافقة (الاسم المعرِّف بين قوسين) |
---|---|---|---|
سلسلة | GraphQL | النص | نص bit(n)، varbit(n) char(n)، varchar(n) |
Int | GraphQL | int | Int2 (smallint, smallserial)، int4 (integer, int, serial) |
عائم | GraphQL | float8 | float4 (عدد حقيقي) float8 (عدد فاصل عائم للدقة المزدوجة) numeric (عدد عشري) |
منطقي | GraphQL | قيمة منطقية | قيمة منطقية |
معرِّف فريد عالمي (UUID) | مخصَّص | uuid | uuid |
Int64 | مخصَّص | bigint | int8 (bigint, bigserial) numeric (decimal) |
التاريخ | مخصَّص | date | التاريخ |
الطابع الزمني | مخصَّص | timestamptz | timestamptz ملاحظة: لا يتم تخزين معلومات المنطقة الزمنية المحلية. |
المتّجه | مخصَّص | vector | المتّجه اطّلِع على إجراء بحث عن التشابه في المتّجهات باستخدام 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
...
تسمح لك لغة تعريف المخطط أيضًا بتحديد أسماء
للعمليات بشكل صريح باستخدام وسيطات التوجيه singular
وplural
.
توجيهات لطلبات البحث والطفرات
بالإضافة إلى التوجيهات التي تستخدمها في تحديد الأنواع والجداول، يقدّم Data Connect توجيهات @auth
و@check
و@redact
و
@transaction
لتحسين سلوك طلبات البحث والطفرات.
توجيه | تنطبق على | الوصف |
---|---|---|
@auth |
طلبات البحث والطفرات | تحدِّد سياسة المصادقة لطلب بحث أو عملية تعديل. راجِع دليل التفويض والإقرار. |
@check |
طلبات البحث عن بيانات التفويض | للتحقّق من توفّر حقول محدّدة في نتائج طلب البحث يتم استخدام تعبير لغة التعبير الشائعة (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
في المثال الجاري، استخدام مَعلمة key
التي تقبل مقياسًا لمفتاح.
يمكنك تمرير مقياس مفتاح كقيمة ثابتة. ولكن يمكنك تحديد متغيّرات لتمرير المقاييس الرئيسية كإدخال.
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
في
الطلبات الضمنية التي تم إنشاؤها.
ستُجري تعديلات على المخطّط من النسخة الأولية.
من عدّة مصادر إلى مصدر واحد
لنضيف مراجعات إلى تطبيقنا، مع جدول Review
وتعديلات على User
.
# Users
# Suppose a user can leave reviews for movies
# user:reviews is a one to many relationship,
# movie:reviews is a one to many relationship,
# movie:user is a many to many relationship
type User
@table(name: "Users", singular: "user", plural: "users", key: ["id"]) {
id: UUID! @col(name: "user_id") @default(expr: "uuidV4()")
auth: String @col(name: "user_auth") @default(expr: "auth.uid")
username: String! @col(name: "username", dataType: "varchar(30)")
# The following are generated from the @ref in the Review table
# reviews_on_user
# movies_via_Review
}
# Reviews
type Review @table(name: "Reviews", key: ["movie", "user"]) {
id: UUID! @col(name: "review_id") @default(expr: "uuidV4()")
user: User! @ref
movie: Movie! @ref
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
description
}
dislikedMovies: movies_via_review(where: { rating: { le: 2 } }) {
title
genre
description
}
}
}
اجتماعات فردية
يمكنك الاطّلاع على النمط. في ما يلي، تم تعديل المخطّط للتوضيح.
# 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) للويب وحزمة تطوير برامج (SDK) لنظام التشغيل Android وحزمة تطوير برامج (SDK) لنظام التشغيل iOS و حزمة تطوير برامج (SDK) لنظام التشغيل Flutter تم إنشاؤها تلقائيًا.