Firebase Data Connect به شما امکان می دهد برای نمونه های PostgreSQL خود که با Google Cloud SQL مدیریت می شوند، رابط ایجاد کنید. این رابطها ترکیبی از پرس و جو و جهش برای استفاده از دادههای شما از طرح شما هستند.
راهنمای شروع یک طرح برنامه بررسی فیلم برای PostgreSQL معرفی شد.
آن راهنما همچنین هر دو عملیات اداری قابل استقرار و موقت، از جمله جهش ها را معرفی کرد.
- جهشهای قابل استقرار، جهشهایی هستند که برای فراخوانی از برنامههای مشتری در یک رابط، با نقاط پایانی API که شما تعریف میکنید، پیادهسازی میکنید. Data Connect احراز هویت و مجوز را در این جهش ها ادغام می کند و SDK های مشتری را بر اساس API شما ایجاد می کند.
- جهشهای اداری موقت از محیطهای ممتاز برای پر کردن و مدیریت جداول اجرا میشوند. میتوانید آنها را در کنسول Firebase ، از محیطهای دارای امتیاز با استفاده از Firebase Admin SDK و در محیطهای توسعه محلی با استفاده از افزونه Data Connect VS Code ایجاد و اجرا کنید.
این راهنما نگاهی عمیقتر به جهشهای قابل استقرار دارد.
ویژگی های جهش های Data Connect
Data Connect به شما امکان می دهد جهش های اساسی را با تمام روش هایی که از پایگاه داده PostgreSQL انتظار دارید انجام دهید:
- عملیات CRUD را انجام دهید
- عملیات چند مرحله ای را با تراکنش ها مدیریت کنید
اما با افزونه های Data Connect برای GraphQL، می توانید جهش های پیشرفته را برای برنامه های سریعتر و کارآمدتر پیاده سازی کنید:
- از اسکالرهای کلیدی بازگردانده شده توسط بسیاری از عملیات برای ساده کردن عملیات تکراری روی رکوردها استفاده کنید
- از مقادیر سرور برای پر کردن داده ها با عملیات ارائه شده توسط سرور استفاده کنید
- در طول عملیات جهش چند مرحله ای برای جستجوی داده ها، صرفه جویی در خطوط کد و رفت و برگشت به سرور، پرس و جوها را انجام دهید.
از فیلدهای ایجاد شده برای اجرای جهش استفاده کنید
عملیات Data Connect شما مجموعه ای از فیلدها را گسترش می دهد که به طور خودکار Data Connect تولید می شود بر اساس انواع و روابط نوع در طرح شما. هر زمان که شما طرحواره خود را ویرایش می کنید، این فیلدها توسط ابزارهای محلی ایجاد می شوند.
میتوانید از فیلدهای ایجاد شده برای پیادهسازی جهشها، از ایجاد، بهروزرسانی و حذف رکوردهای فردی در جداول واحد گرفته تا بهروزرسانیهای چند جدولی پیچیدهتر استفاده کنید. فرض کنید طرح شما حاوی یک نوع Movie
و یک نوع Actor
مرتبط است. Data Connect فیلدهای movie_insert
، movie_update
، movie_delete
و موارد دیگر را ایجاد میکند.
جهش با
قسمت movie_insert
فیلد | از این قسمت برای ایجاد یک فیلم استفاده کنید. mutation CreateMovie($data: Movie_Data!) { movie_insert(data: $data) { key } } |
جهش با
قسمت movie_update
فیلد | از این فیلد برای بهروزرسانی یک فیلم با کلید آن استفاده کنید. mutation UpdateMovie($myKey: Movie_Key!, $data: Movie_Data!) { movie_update(key: $myKey, data: $data) { key } } |
جهش با
قسمت movie_delete
فیلد | از این فیلد برای حذف یک فیلم با کلید آن استفاده کنید. mutation DeleteMovie($myKey: Movie_Key!) { movie_delete(key: $myKey) { key } } |
عناصر ضروری یک جهش
جهش های Data Connect جهش های GraphQL با پسوندهای Data Connect هستند. درست مانند یک جهش معمولی GraphQL، می توانید نام عملیات و لیستی از متغیرهای GraphQL را تعریف کنید.
Data Connect پرس و جوهای GraphQL را با دستورالعمل های سفارشی مانند @auth
و @transaction
گسترش می دهد.
بنابراین جهش زیر دارد:
- تعریف نوع
mutation
- نام عملیات
SignUp
(جهش). - یک آرگومان عملیاتی
$username
یک متغیر - یک دستورالعمل واحد،
@auth
- یک فیلد
user_insert
.
mutation SignUp($username: String!) @auth(level: USER) {
user_insert(data: {
id_expr: "auth.uid"
username: $username
})
}
هر آرگومان جهشی نیاز به یک اعلان نوع، یک نوع داخلی مانند String
یا یک نوع سفارشی و با طرحواره تعریف شده مانند Movie
دارد.
جهش های اساسی را بنویسید
می توانید برای ایجاد، به روز رسانی و حذف رکوردهای فردی از پایگاه داده خود شروع به نوشتن جهش کنید.
ایجاد کنید
بیایید کارهای اساسی انجام دهیم.
# 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"
})
}
به روز رسانی را انجام دهید
در اینجا به روز رسانی است. تهیهکنندگان و کارگردانان مطمئناً امیدوارند که این رتبهبندیهای متوسط رو به رشد باشد.
فیلد movie_update
حاوی یک آرگومان id
مورد انتظار برای شناسایی یک رکورد و یک فیلد data
است که می توانید از آن برای تنظیم مقادیر در این به روز رسانی استفاده کنید.
mutation UpdateMovie(
$id: UUID!,
$genre: String!,
$rating: Int!,
$description: String!
) {
movie_update(id: $id,
data: {
genre: $genre
rating: $rating
description: $description
})
}
برای انجام چندین به روز رسانی، از قسمت movie_updateMany
استفاده کنید.
# Multiple updates (increase all ratings of a genre)
mutation IncreaseRatingForGenre($genre: String!, $rating: Int!) {
movie_updateMany(
where: { genre: { eq: $genre } },
data:
{
rating: $rating
})
}
با استفاده از _update
از عملیات افزایش، کاهش، الحاق و پیشپرداخت استفاده کنید
در حالی که در جهشهای _update
و _updateMany
میتوانید بهصراحت مقادیری را در data:
اغلب اعمال عملگرهایی مانند افزایش برای بهروزرسانی مقادیر منطقیتر است.
برای اصلاح مثال بهروزرسانی قبلی، فرض کنید میخواهید امتیاز یک فیلم خاص را افزایش دهید. می توانید از نحو rating_update
با عملگر inc
استفاده کنید.
mutation UpdateMovie(
$id: UUID!,
$ratingIncrement: Int!
) {
movie_update(id: $id, data: {
rating_update: {
inc: $ratingIncrement
}
})
}
Data Connect از اپراتورهای زیر برای بهروزرسانیهای میدانی پشتیبانی میکند:
-
inc
افزایش انواع داده هایInt
,Int64
,Float
,Date
وTimestamp
-
dec
تا کاهش انواع داده هایInt
,Int64
,Float
,Date
وTimestamp
برای فهرستها، میتوانید با مقادیر فردی یا فهرست مقادیر با استفاده از:
- اگر آیتم(های) از قبل در انواع لیست وجود ندارد، به جز لیست های برداری، به ضمیمه
add
-
remove
برای حذف همه موارد، در صورت وجود، از انواع لیست، به جز لیست های برداری -
append
به افزودن آیتم(ها) به انواع لیست، به جز لیست های برداری -
prepend
برای اضافه کردن آیتم(ها) به انواع لیست، به جز لیست های برداری
حذف ها را انجام دهید
البته می توانید داده های فیلم را حذف کنید. محافظان فیلم مطمئناً مایلند که فیلمهای فیزیکی تا زمانی که ممکن است نگهداری شوند.
# 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 دو ویژگی مهم را ارائه می دهد که به شما امکان می دهد جهش های کارآمدتری بنویسید و عملیات رفت و برگشت را ذخیره کنید.
اسکالرهای کلیدی شناسه های شی مختصر هستند که Data Connect به طور خودکار از فیلدهای کلیدی در طرحواره های شما جمع آوری می کند. اسکالرهای کلیدی در مورد کارایی هستند و به شما امکان می دهند در یک تماس اطلاعاتی درباره هویت و ساختار داده های خود پیدا کنید. آنها به ویژه زمانی مفید هستند که می خواهید اقدامات متوالی را روی رکوردهای جدید انجام دهید و به یک شناسه منحصر به فرد برای ارسال به عملیات آینده نیاز دارید، و همچنین زمانی که می خواهید به کلیدهای رابطه ای برای انجام عملیات پیچیده تر اضافی دسترسی داشته باشید.
با استفاده از مقادیر سرور ، می توانید به طور موثر به سرور اجازه دهید فیلدهای جداول شما را با استفاده از مقادیر ذخیره شده یا قابل محاسبه بر اساس عبارات خاص CEL سمت سرور در آرگومان expr
به صورت پویا پر کند. به عنوان مثال، میتوانید فیلدی را تعریف کنید که وقتی به فیلد با استفاده از زمان ذخیرهشده در یک درخواست عملیات دسترسی داده میشود، یک مهر زمانی اعمال میشود updatedAt: Timestamp! @default(expr: "request.time")
.
جهش های پیشرفته بنویسید: اجازه دهید Data Connect مقادیر را با استفاده از نحو field_expr
عرضه کند
همانطور که در اسکالرهای کلیدی و مقادیر سرور بحث شد، میتوانید طرحواره خود را طوری طراحی کنید که سرور مقادیر فیلدهای رایج مانند id
و تاریخها را در پاسخ به درخواستهای مشتری پر کند.
علاوه بر این، میتوانید از دادههایی مانند شناسههای کاربری ارسال شده در اشیاء request
Data Connect از برنامههای مشتری استفاده کنید.
وقتی جهشها را پیادهسازی میکنید، از نحو field_expr
برای راهاندازی بهروزرسانیهای تولید شده توسط سرور یا دسترسی به دادههای درخواستها استفاده کنید. به عنوان مثال، برای انتقال uid
مجوز ذخیره شده در یک درخواست به یک عملیات _upsert
، "auth.uid"
را در قسمت userId_expr
ارسال کنید.
# Add a movie to the user's favorites list
mutation AddFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId })
}
# Remove a movie from the user's favorites list
mutation DeleteFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie_delete(key: { userId_expr: "auth.uid", movieId: $movieId })
}
یا در یک برنامه آشنای فهرست کارها، هنگام ایجاد یک لیست کارهای جدید، میتوانید id_expr
برای دستور دادن به سرور برای ایجاد خودکار یک UUID برای لیست ارسال کنید.
mutation CreateTodoListWithFirstItem(
$listName: String!
) @transaction {
# Step 1
todoList_insert(data: {
id_expr: "uuidV4()", # <-- auto-generated. Or a column-level @default on `type TodoList` will also work
name: $listName,
})
}
برای اطلاعات بیشتر، به اسکالرهای _Expr
در مرجع اسکالرها مراجعه کنید.
جهش های پیشرفته را بنویسید: عملیات چند مرحله ای
موقعیتهای زیادی وجود دارد که ممکن است بخواهید چندین فیلد نوشتن (مانند درجها) را در یک جهش قرار دهید. همچنین ممکن است بخواهید پایگاه داده خود را در حین اجرای یک جهش بخوانید تا قبل از انجام، به عنوان مثال، درج یا به روز رسانی، داده های موجود را جستجو و تأیید کنید. این گزینه ها باعث صرفه جویی در عملیات رفت و برگشت و در نتیجه هزینه ها می شود.
Data Connect به شما امکان می دهد منطق چند مرحله ای را در جهش های خود با پشتیبانی از:
چندین فیلد نوشتن
چندین فیلد خوانده شده در جهش های شما (با استفاده از کلمه کلیدی فیلد
query
).دستورالعمل
@transaction
، که پشتیبانی از تراکنش های آشنا از پایگاه های داده رابطه ای را فراهم می کند.دستورالعمل
@check
، که به شما امکان می دهد محتوای خوانده شده را با استفاده از عبارات CEL و بر اساس نتایج چنین ارزیابی ارزیابی کنید:- به ایجاد، به روز رسانی و حذف تعریف شده توسط یک جهش ادامه دهید
- برای بازگرداندن نتایج یک فیلد پرس و جو ادامه دهید
- از پیام های برگشتی برای اجرای منطق مناسب در کد مشتری خود استفاده کنید
دستورالعمل
@redact
، که به شما امکان می دهد نتایج فیلد پرس و جو را از نتایج پروتکل سیمی حذف کنید.اتصال
response
CEL، که نتایج انباشته شده از تمام جهش ها و پرس و جوهای انجام شده در یک عملیات پیچیده و چند مرحله ای را ذخیره می کند. شما می توانید به پیوندresponse
دسترسی داشته باشید:- در دستورات
@check
، از طریق آرگومانexpr:
- با مقادیر سرور، با استفاده از نحو
field_expr
- در دستورات
دستورالعمل @transaction
پشتیبانی از جهش های چند مرحله ای شامل مدیریت خطا با استفاده از تراکنش ها می شود.
دستورالعمل @transaction
بر این امر تاکید میکند که یک جهش - با یک فیلد نوشتن (مثلاً _insert
یا _update
) یا با چندین فیلد نوشتن - همیشه در یک تراکنش پایگاه داده اجرا میشود.
جهش های بدون
@transaction
هر فیلد ریشه را یکی پس از دیگری به ترتیب اجرا می کنند. عملیات هر گونه خطا را به عنوان خطای میدانی جزئی نشان می دهد، اما تأثیرات اجرای بعدی را ندارد.جهش با
@transaction
تضمین شده است که یا به طور کامل موفق شود یا به طور کامل شکست بخورد. اگر هر یک از فیلدهای داخل تراکنش از کار بیفتد، کل تراکنش برگردانده می شود.
دستورالعملهای @check
و @redact
دستور @check
تأیید می کند که فیلدهای مشخص شده در نتایج پرس و جو وجود دارند. یک عبارت Common Expression Language (CEL) برای آزمایش مقادیر فیلد استفاده می شود. رفتار پیشفرض دستورالعمل بررسی و رد گرههایی است که مقدار آنها null
یا []
(لیستهای خالی) است.
دستور @redact
بخشی از پاسخ مشتری را ویرایش می کند. فیلدهای ویرایش شده هنوز از نظر عوارض جانبی (از جمله تغییرات دادهها و @check
) ارزیابی میشوند و نتایج هنوز برای مراحل بعدی در عبارات CEL در دسترس هستند.
@check
، @check(message:)
و @redact
استفاده کنید
یک کاربرد عمده برای @check
و @redact
جستجوی دادههای مرتبط برای تصمیمگیری در مورد اینکه آیا عملیات خاصی باید مجاز باشند یا خیر، با استفاده از جستجو در منطق اما پنهان کردن آن از مشتریان است. درخواست شما می تواند پیام های مفیدی را برای مدیریت صحیح در کد مشتری برگرداند.
برای مثال، فیلد جستجوی زیر بررسی میکند که آیا درخواستکننده نقش «مدیر» مناسبی برای مشاهده کاربرانی که میتوانند یک فیلم را ویرایش کنند، دارد یا خیر.
query GetMovieEditors($movieId: UUID!) @auth(level: USER) {
moviePermission(key: { movieId: $movieId, userId_expr: "auth.uid" }) @redact {
role @check(expr: "this == 'admin'", message: "You must be an admin to view all editors of a movie.")
}
moviePermissions(where: { movieId: { eq: $movieId }, role: { eq: "editor" } }) {
user {
id
username
}
}
}
برای کسب اطلاعات بیشتر درباره دستورالعملهای @check
و @redact
در بررسیهای مجوز، به بحث جستجوی دادههای مجوز مراجعه کنید.
برای تأیید اعتبار کلیدها از @check
استفاده کنید
برخی از فیلدهای جهش، مانند _update
، اگر رکوردی با یک کلید مشخص وجود نداشته باشد، ممکن است غیرفعال شوند. به طور مشابه، جستجوها ممکن است یک لیست خالی یا خالی برگردانند. اینها خطا در نظر گرفته نمی شوند و بنابراین باعث بازگشت مجدد نمی شوند.
برای محافظت در برابر این نتیجه، تست کنید که آیا کلیدها را می توان با استفاده از دستور @check
پیدا کرد.
# Delete by key, error if not found
mutation MustDeleteMovie($id: UUID!) @transaction {
movie_delete(id: $id) @check(expr: "this != null", message: "Movie not found, therefore nothing is deleted")
}
از پیوند response
برای زنجیره جهش های چند مرحله ای استفاده کنید
رویکرد اساسی برای ایجاد رکوردهای مرتبط، به عنوان مثال یک Movie
جدید و یک ورودی MovieMetadata
مرتبط، به این صورت است:
- یک جهش
_insert
را برایMovie
فراخوانی کنید - کلید برگشتی فیلم ایجاد شده را ذخیره کنید
- سپس، یک جهش
_insert
دوم را برای ایجاد رکوردMovieMetadata
فراخوانی کنید.
اما با Data Connect میتوانید با دسترسی به نتایج اولین _insert
در دومین _insert
، این مورد رایج را در یک عملیات چند مرحلهای مدیریت کنید.
ساختن یک اپلیکیشن بررسی فیلم موفق کار بسیار زیادی است. بیایید لیست کارهای خود را با یک مثال جدید دنبال کنیم.
از response
برای تنظیم فیلدها با مقادیر سرور استفاده کنید
در جهش لیست کارهای زیر:
- پیوند
response
نشان دهنده شی پاسخ جزئی تا کنون است، که شامل تمام فیلدهای جهش سطح بالا قبل از فیلد فعلی است. - نتایج عملیات
todoList_insert
اولیه، که فیلدid
(کلید) را برمی گرداند، بعداً درresponse.todoList_insert.id
قابل دسترسی است تا بتوانیم فوراً یک مورد جدید را وارد کنیم.
mutation CreateTodoListWithFirstItem(
$listName: String!,
$itemContent: String!
) @transaction {
# Sub-step 1:
todoList_insert(data: {
id_expr: "uuidV4()", # <-- auto-generated. Or a column-level @default on `type TodoList` will also work
name: $listName,
})
# Sub-step 2:
todo_insert(data: {
listId_expr: "response.todoList_insert.id" # <-- Grab the newly generated ID from the partial response so far.
content: $itemContent,
})
}
از response
برای اعتبارسنجی فیلدها با استفاده از @check
استفاده کنید
response
در @check(expr: "...")
نیز موجود است، بنابراین می توانید از آن برای ایجاد منطق سمت سرور حتی پیچیده تر استفاده کنید. در ترکیب با مراحل query { … }
در جهشها، میتوانید بدون هیچ گونه رفت و برگشتی مشتری-سرور اضافی به چیزهای بیشتری دست یابید.
در مثال زیر، توجه داشته باشید: که @check
قبلاً به response.query
دسترسی دارد زیرا یک @check
همیشه بعد از مرحله ای که به آن متصل شده است اجرا می شود.
mutation CreateTodoInNamedList(
$listName: String!,
$itemContent: String!
) @transaction {
# Sub-step 1: Look up List.id by its name
query
@check(expr: "response.query.todoLists.size() > 0", message: "No such TodoList with the name!")
@check(expr: "response.query.todoLists.size() < 2", message: "Ambiguous listName!") {
todoLists(where: { name: $listName }) {
id
}
}
# Sub-step 2:
todo_insert(data: {
listId_expr: "response.todoLists[0].id" # <-- Now we have the parent list ID to insert to
content: $itemContent,
})
}
برای اطلاعات بیشتر در مورد اتصال response
، به مرجع CEL مراجعه کنید.
درک عملیات قطع شده با @transaction
و query @check
جهش های چند مرحله ای می توانند با خطاهایی روبرو شوند:
- عملیات پایگاه داده ممکن است شکست بخورد.
- query
@check
logic ممکن است عملیات را خاتمه دهد.
Data Connect توصیه می کند که از دستورالعمل @transaction
با جهش های چند مرحله ای خود استفاده کنید. این منجر به یک پایگاه داده منسجم تر و نتایج جهش می شود که در کد مشتری راحت تر قابل کنترل هستند:
- در اولین خطا یا عدم موفقیت
@check
، عملیات خاتمه می یابد، بنابراین نیازی به مدیریت اجرای هیچ یک از فیلدهای بعدی یا ارزیابی CEL نیست. - بازگشتها در پاسخ به خطاهای پایگاه داده یا منطق
@check
انجام میشوند و وضعیت پایگاه داده ثابتی را به دست میدهند. - یک خطای بازگشت همیشه به کد مشتری بازگردانده می شود.
ممکن است موارد استفاده ای وجود داشته باشد که شما ترجیح می دهید از @transaction
استفاده نکنید: برای مثال اگر به توان عملیاتی، مقیاس پذیری یا در دسترس بودن بیشتری نیاز دارید، ممکن است ثبات نهایی را انتخاب کنید. با این حال، شما باید پایگاه داده و کد مشتری خود را مدیریت کنید تا نتایج را بدست آورید:
- اگر یک فیلد به دلیل عملیات پایگاه داده از کار بیفتد، فیلدهای بعدی به اجرا ادامه خواهند داد. با این حال،
@check
ناموفق همچنان کل عملیات را خاتمه می دهد. - بازگشتها انجام نمیشوند، به این معنی که یک وضعیت پایگاه داده مختلط با برخی بهروزرسانیهای موفق و برخی بهروزرسانیهای ناموفق.
- اگر منطق
@check
شما از نتایج خواندن و/یا نوشتن در مرحله قبل استفاده کند، عملیات شما با@check
ممکن است نتایج متناقض تری داشته باشد. - نتیجه ای که به کد مشتری بازگردانده می شود حاوی ترکیب پیچیده تری از پاسخ های موفقیت و شکست خواهد بود.
دستورالعمل برای جهش های Data Connect
علاوه بر دستورالعملهایی که در تعریف انواع و جداول استفاده میکنید، Data Connect دستورات @auth
، @check
، @redact
و @transaction
را برای تقویت رفتار عملیات ارائه میکند.
بخشنامه | قابل اجرا برای | توضیحات |
---|---|---|
@auth | پرس و جو و جهش | خط مشی مجوز برای یک پرس و جو یا جهش را تعریف می کند. راهنمای مجوز و گواهینامه را ببینید. |
@check | فیلدهای query در عملیات چند مرحله ای | بررسی می کند که فیلدهای مشخص شده در نتایج پرس و جو وجود دارد. یک عبارت Common Expression Language (CEL) برای آزمایش مقادیر فیلد استفاده می شود. به عملیات چند مرحله ای مراجعه کنید. |
@redact | پرس و جوها | بخشی از پاسخ مشتری را ویرایش می کند. به عملیات چند مرحله ای مراجعه کنید. |
@transaction | جهش ها | الزام می کند که یک جهش همیشه در یک تراکنش پایگاه داده اجرا شود. به عملیات چند مرحله ای مراجعه کنید. |
مراحل بعدی
ممکن است علاقه مند باشید:
- ایجاد جهش برای برنامه های شما با استفاده از ابزارهای کمکی هوش مصنوعی
- مجوز جهش های خود را بر اساس راهنمای مجوز
- فراخوانی جهش ها از کد مشتری خود برای وب ، iOS ، اندروید و فلاتر .
- انجام عملیات داده انبوه با جهش