Firebase Data Connect cho phép bạn tạo trình kết nối cho các phiên bản PostgreSQL được quản lý bằng Google Cloud SQL. Các trình kết nối này là sự kết hợp của một giản đồ, truy vấn và đột biến để sử dụng dữ liệu của bạn.
Hướng dẫn bắt đầu đã giới thiệu giản đồ ứng dụng đánh giá phim cho PostgreSQL và hướng dẫn này sẽ xem xét kỹ hơn về cách thiết kế giản đồ Data Connect cho PostgreSQL.
Hướng dẫn này sẽ ghép nối các truy vấn và đột biến Data Connect với các ví dụ về giản đồ. Tại sao chúng ta lại thảo luận về truy vấn (và sự thay đổi) trong hướng dẫn về schema Data Connect? Giống như các nền tảng dựa trên GraphQL khác, Firebase Data Connect là một nền tảng phát triển ưu tiên truy vấn. Vì vậy, với tư cách là một nhà phát triển, trong quá trình lập mô hình dữ liệu, bạn sẽ phải suy nghĩ về dữ liệu mà khách hàng của mình cần. Điều này sẽ ảnh hưởng rất lớn đến giản đồ dữ liệu mà bạn phát triển cho dự án của mình.
Hướng dẫn này bắt đầu bằng một giản đồ mới cho bài đánh giá phim, sau đó trình bày về truy vấn và sự thay đổi bắt nguồn từ giản đồ đó, cuối cùng cung cấp danh sách SQL tương đương với giản đồ Data Connect cốt lõi.
Sơ đồ cho ứng dụng đánh giá phim
Giả sử bạn muốn xây dựng một dịch vụ cho phép người dùng gửi và xem bài đánh giá phim.
Bạn cần có một giản đồ ban đầu cho ứng dụng như vậy. Bạn sẽ mở rộng giản đồ này sau đó để tạo các truy vấn quan hệ phức tạp.
Bảng phim
Giản đồ cho Phim chứa các lệnh chính như:
@table
, cho phép chúng ta đặt tên cho toán tử bằng cách sử dụng đối sốsingular
vàplural
@col
để đặt tên cột một cách rõ ràng@default
để cho phép đặt giá trị mặc định.
# 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")
}
Giá trị máy chủ và đại lượng vô hướng khoá
Trước khi xem ứng dụng đánh giá phim, hãy giới thiệu Data Connect giá trị máy chủ và giá trị vô hướng chính.
Khi sử dụng giá trị máy chủ, bạn có thể cho phép máy chủ tự động điền các trường trong bảng bằng cách sử dụng các giá trị đã lưu trữ hoặc dễ dàng tính toán theo các biểu thức cụ thể phía máy chủ. Ví dụ: bạn có thể xác định một trường có dấu thời gian được áp dụng khi truy cập vào trường đó bằng biểu thức updatedAt: Timestamp! @default(expr: "request.time")
.
Đại lượng vô hướng chính là giá trị nhận dạng đối tượng ngắn gọn mà Data Connect tự động ghép nối từ các trường chính trong giản đồ. Số thực đơn biến là về hiệu quả, cho phép bạn tìm thấy trong một lệnh gọi thông tin về danh tính và cấu trúc của dữ liệu. Các khoá này đặc biệt hữu ích khi bạn muốn thực hiện các thao tác tuần tự trên các bản ghi mới và cần một giá trị nhận dạng duy nhất để truyền đến các thao tác sắp tới, cũng như khi bạn muốn truy cập vào các khoá quan hệ để thực hiện các thao tác phức tạp hơn.
Bảng siêu dữ liệu của phim
Bây giờ, hãy theo dõi các đạo diễn phim, cũng như thiết lập mối quan hệ một với một với Movie
.
Thêm lệnh @ref
để xác định mối quan hệ.
# 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 và MovieActor
Tiếp theo, bạn muốn các diễn viên đóng vai chính trong phim của mình. Vì bạn có mối quan hệ nhiều với nhiều giữa phim và diễn viên, hãy tạo một bảng nối.
# 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
}
Người dùng
Cuối cùng, người dùng ứng dụng của bạn.
# 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
}
Loại dữ liệu được hỗ trợ
Data Connect hỗ trợ các loại dữ liệu vô hướng sau đây, với các giá trị gán cho các loại PostgreSQL bằng @col(dataType:)
.
Loại Data Connect | Loại tích hợp sẵn GraphQL hoặc loại tuỳ chỉnh Data Connect |
Loại PostgreSQL mặc định | Các loại PostgreSQL được hỗ trợ (bí danh trong ngoặc đơn) |
---|---|---|---|
Chuỗi | GraphQL | văn bản | text bit(n), varbit(n) char(n), varchar(n) |
Int | GraphQL | int | Int2 (smallint, smallserial), int4 (integer, int, serial) |
Nổi | GraphQL | float8 | float4 (thực) float8 (độ chính xác kép) số (thập phân) |
Boolean | GraphQL | boolean | boolean |
mã nhận dạng duy nhất (UUID) | Tuỳ chỉnh | uuid | uuid |
Int64 | Tuỳ chỉnh | bigint | int8 (bigint, bigserial) số (thập phân) |
Ngày | Tuỳ chỉnh | ngày | ngày |
Dấu thời gian | Tuỳ chỉnh | timestamptz | timestamptz Lưu ý: Thông tin về múi giờ tại địa phương không được lưu trữ. |
Vectơ | Tuỳ chỉnh | vector | vectơ |
- GraphQL
List
liên kết đến một mảng một chiều.- Ví dụ:
[Int]
liên kết đếnint5[]
,[Any]
liên kết đếnjsonb[]
. - Data Connect không hỗ trợ mảng lồng nhau.
- Ví dụ:
Các truy vấn và đột biến ngầm ẩn và được xác định trước
Các truy vấn và đột biến Data Connect sẽ mở rộng một tập hợp truy vấn ngầm ẩn và đột biến ngầm ẩn do Data Connect tạo ra dựa trên các loại và mối quan hệ loại trong giản đồ. Các truy vấn và đột biến ngầm ẩn được tạo bằng công cụ cục bộ bất cứ khi nào bạn chỉnh sửa giản đồ.
Trong quá trình phát triển, bạn sẽ triển khai các truy vấn được xác định trước và các đột biến được xác định trước dựa trên các thao tác ngầm ẩn này.
Tên truy vấn và đột biến ngầm ẩn
Data Connect suy luận tên phù hợp cho các truy vấn và đột biến ngầm ẩn từ nội dung khai báo loại giản đồ. Ví dụ: khi làm việc với nguồn PostgreSQL, nếu bạn xác định một bảng có tên là Movie
, máy chủ sẽ tạo ngầm ẩn:
- Truy vấn cho các trường hợp sử dụng bảng đơn có tên thân thiện
movie
(số ít, để truy xuất kết quả riêng lẻ truyền các đối số nhưeq
) vàmovies
(số nhiều, để truy xuất danh sách kết quả truyền các đối số nhưgt
và các thao tác nhưorderby
). Data Connect cũng tạo truy vấn cho các thao tác đa bảng, quy chiếu có tên rõ ràng nhưactors_on_movies
hoặcactors_via_actormovie
. - Các đột biến có tên là
movie_insert
,movie_upsert
...
Ngôn ngữ định nghĩa giản đồ cũng cho phép bạn đặt tên rõ ràng cho các thao tác bằng cách sử dụng đối số lệnh singular
và plural
.
Chỉ thị cho truy vấn và đột biến
Ngoài các lệnh mà bạn sử dụng để xác định loại và bảng, Data Connect còn cung cấp các lệnh @auth
, @check
, @redact
và @transaction
để tăng cường hành vi của truy vấn và đột biến.
Chỉ thị | Áp dụng cho | Mô tả |
---|---|---|
@auth |
Truy vấn và đột biến | Xác định chính sách xác thực cho một truy vấn hoặc đột biến. Xem hướng dẫn uỷ quyền và chứng thực. |
@check |
Truy vấn tra cứu dữ liệu uỷ quyền | Xác minh rằng các trường được chỉ định có trong kết quả truy vấn. Biểu thức Ngôn ngữ diễn đạt thông thường (CEL) được dùng để kiểm thử giá trị trường. Xem hướng dẫn uỷ quyền và chứng thực. |
@redact |
Cụm từ tìm kiếm | Xoá một phần nội dung phản hồi của ứng dụng khách. Xem hướng dẫn uỷ quyền và chứng thực. |
@transaction |
Đột biến | Thực thi để một đột biến luôn chạy trong một giao dịch cơ sở dữ liệu. Xem ví dụ về đột biến ứng dụng phim. |
Truy vấn cho cơ sở dữ liệu bài đánh giá phim
Bạn xác định truy vấn Data Connect bằng cách khai báo loại thao tác truy vấn, tên thao tác, không có hoặc có đối số thao tác và không có hoặc có lệnh có đối số.
Trong phần hướng dẫn nhanh, truy vấn listEmails
mẫu không có tham số nào. Tất nhiên, trong nhiều trường hợp, dữ liệu được truyền đến các trường truy vấn sẽ mang tính động. Bạn có thể sử dụng cú pháp $variableName
để xử lý các biến dưới dạng một trong các thành phần của định nghĩa truy vấn.
Vì vậy, truy vấn sau đây có:
- Định nghĩa kiểu
query
- Tên toán tử (truy vấn)
ListMoviesByGenre
- Một đối số thao tác
$genre
biến - Một lệnh duy nhất,
@auth
.
query ListMoviesByGenre($genre: String!) @auth(level: USER)
Mỗi đối số truy vấn đều yêu cầu một nội dung khai báo kiểu, một nội dung tích hợp sẵn như String
hoặc một kiểu tuỳ chỉnh, do giản đồ xác định như Movie
.
Hãy xem chữ ký của các truy vấn ngày càng phức tạp. Cuối cùng, bạn sẽ giới thiệu các biểu thức mối quan hệ mạnh mẽ, súc tích có trong các truy vấn ngầm ẩn mà bạn có thể xây dựng trong các truy vấn được xác định trước.
Số thực chính trong truy vấn
Nhưng trước tiên, hãy lưu ý về đại lượng vô hướng chính.
Data Connect xác định một loại đặc biệt cho các đại lượng vô hướng chính, được xác định bằng _Key
. Ví dụ: loại của một đại lượng vô hướng khoá cho bảng Movie
là Movie_Key
.
Bạn truy xuất các đại lượng vô hướng chính dưới dạng phản hồi do hầu hết các đột biến ngầm ẩn trả về, hoặc tất nhiên là từ các truy vấn mà bạn đã truy xuất tất cả các trường cần thiết để tạo khoá vô hướng.
Các truy vấn tự động số ít, chẳng hạn như movie
trong ví dụ đang chạy, hỗ trợ đối số khoá chấp nhận một đại lượng vô hướng khoá.
Bạn có thể truyền một đại lượng vô hướng khoá dưới dạng một giá trị cố định. Tuy nhiên, bạn có thể xác định các biến để truyền các đại lượng vô hướng khoá làm dữ liệu đầu vào.
query GetMovie($myKey: Movie_Key!) {
movie(key: $myKey) { title }
}
Bạn có thể cung cấp các thông tin này trong yêu cầu JSON như sau (hoặc các định dạng chuyển đổi tuần tự khác):
{
# …
"variables": {
"myKey": {"foo": "some-string-value", "bar": 42}
}
}
Nhờ khả năng phân tích cú pháp vô hướng tuỳ chỉnh, bạn cũng có thể tạo Movie_Key
bằng cách sử dụng cú pháp đối tượng có thể chứa các biến. Điều này chủ yếu hữu ích khi bạn muốn chia các thành phần riêng lẻ thành các biến khác nhau vì một số lý do.
Bí danh trong truy vấn
Data Connect hỗ trợ việc gán bí danh GraphQL trong các truy vấn. Với bí danh, bạn đổi tên dữ liệu được trả về trong kết quả của truy vấn. Một truy vấn Data Connect có thể áp dụng nhiều bộ lọc hoặc các thao tác truy vấn khác trong một yêu cầu hiệu quả đến máy chủ, đồng thời phát hành một số "truy vấn phụ" một cách hiệu quả. Để tránh xung đột tên trong tập dữ liệu được trả về, bạn sử dụng bí danh để phân biệt các truy vấn phụ.
Dưới đây là một truy vấn trong đó biểu thức sử dụng bí danh mostPopular
.
query ReviewTopPopularity($genre: String) {
mostPopular: review(first: {
where: {genre: {eq: $genre}},
orderBy: {popularity: DESC}
}) { … }
}
Truy vấn đơn giản có bộ lọc
Truy vấn Data Connect liên kết với tất cả bộ lọc SQL và thao tác thứ tự phổ biến.
Toán tử where
và orderBy
(truy vấn số ít, số nhiều)
Trả về tất cả các hàng đã so khớp trong bảng (và các mối liên kết lồng nhau). Trả về một mảng trống nếu không có bản ghi nào khớp với bộ lọc.
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}]) { … }
}
Toán tử limit
và offset
(truy vấn số ít, số nhiều)
Bạn có thể phân trang kết quả. Các đối số này được chấp nhận nhưng không được trả về trong kết quả.
query MoviesTop10 {
movies(orderBy: [{ rating: DESC }], limit: 10) {
# graphql: list the fields from the results to return
title
}
}
bao gồm các trường mảng
Bạn có thể kiểm tra để đảm bảo rằng một trường mảng chứa một mục đã chỉ định.
# 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
}
}
Thao tác với chuỗi và biểu thức chính quy
Truy vấn của bạn có thể sử dụng các thao tác so sánh và tìm kiếm chuỗi thông thường, bao gồm cả biểu thức chính quy. Lưu ý để tăng hiệu quả, bạn đang gộp một số thao tác ở đây và phân biệt các thao tác đó bằng bí danh.
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
và and
cho bộ lọc tổng hợp
Sử dụng or
và and
cho logic phức tạp hơn.
query ListMoviesByGenreAndGenre($minRating: Int!, $genre: String) {
movies(
where: { _or: [{ rating: { ge: $minRating } }, { genre: { eq: $genre } }] }
) {
# graphql: list the fields from the results to return
title
}
}
Câu lệnh truy vấn phức tạp
Truy vấn Data Connect có thể truy cập dữ liệu dựa trên mối quan hệ giữa các bảng. Bạn có thể sử dụng mối quan hệ đối tượng (một với một) hoặc mảng (một với nhiều) được xác định trong giản đồ để tạo truy vấn lồng nhau, tức là tìm nạp dữ liệu cho một loại cùng với dữ liệu từ một loại lồng nhau hoặc có liên quan.
Các truy vấn như vậy sử dụng cú pháp Data Connect _on_
và _via
ma thuật trong truy vấn ngầm được tạo.
Bạn sẽ sửa đổi giản đồ từ phiên bản ban đầu của chúng tôi.
Nhiều với một
Hãy thêm bài đánh giá vào ứng dụng của chúng ta, với bảng Review
và các sửa đổi đối với 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")
}
Truy vấn nhiều với một
Bây giờ, hãy xem một truy vấn có sử dụng bí danh để minh hoạ cú pháp _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
}
}
}
Một với một
Bạn có thể thấy mẫu này. Dưới đây là giản đồ được sửa đổi để minh hoạ.
# 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
}
Truy vấn một với một
Bạn có thể truy vấn bằng cú pháp _on_
.
# One to one
query GetMovieMetadata($id: UUID!) @auth(level: PUBLIC) {
movie(id: $id) {
movieMetadatas_on_movie {
director
}
}
}
Nhiều với nhiều
Phim cần diễn viên và diễn viên cần phim. Các lớp này có mối quan hệ nhiều với nhiều mà bạn có thể lập mô hình bằng bảng nối 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!]!
}
Truy vấn nhiều với nhiều
Hãy xem một truy vấn có sử dụng bí danh để minh hoạ cú pháp _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
}
}
}
Các đột biến cho cơ sở dữ liệu bài đánh giá phim
Như đã đề cập, khi bạn xác định một bảng trong giản đồ, Data Connect sẽ tạo các đột biến ngầm ẩn cơ bản cho mỗi bảng.
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!
}
Với những kiến thức này, bạn có thể triển khai các trường hợp CRUD cốt lõi ngày càng phức tạp. Hãy nói nhanh năm lần!
Chỉ thị @transaction
Chỉ thị này thực thi việc một đột biến luôn chạy trong một giao dịch cơ sở dữ liệu.
Các đột biến với @transaction
được đảm bảo sẽ thành công hoàn toàn hoặc không thành công hoàn toàn. Nếu có trường nào trong giao dịch không thành công, toàn bộ giao dịch sẽ được hoàn tác. Từ quan điểm của máy khách, mọi lỗi đều hoạt động như thể toàn bộ yêu cầu đã không thành công do lỗi yêu cầu và quá trình thực thi chưa bắt đầu.
Các đột biến không có @transaction
sẽ thực thi từng trường gốc theo trình tự. Lỗi này hiển thị dưới dạng lỗi trường một phần, nhưng không ảnh hưởng đến các lần thực thi tiếp theo.
Tạo
Hãy tạo các thành phần cơ bản.
# 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
})
}
Hoặc một thao tác chèn mới.
# 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"
})
}
Thực hiện cập nhật
Sau đây là thông tin cập nhật. Nhà sản xuất và đạo diễn chắc chắn hy vọng những điểm xếp hạng trung bình đó sẽ tăng lên.
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 } }
)
}
Thực hiện xoá
Tất nhiên, bạn có thể xoá dữ liệu phim. Những người bảo tồn phim chắc chắn sẽ muốn duy trì phim vật lý lâu nhất có thể.
# Delete by key
mutation DeleteMovie($id: UUID!) {
movie_delete(id: $id)
}
Tại đây, bạn có thể sử dụng _deleteMany
.
# Multiple deletes
mutation DeleteUnpopularMovies($minRating: Int!) {
movie_deleteMany(where: { rating: { le: $minRating } })
}
Viết các đột biến trên mối quan hệ
Quan sát cách sử dụng đột biến _upsert
ngầm ẩn trên một mối quan hệ.
# Create or update a one to one relation
mutation MovieMetadataUpsert($movieId: UUID!, $director: String!) {
movieMetadata_upsert(
data: { movie: { id: $movieId }, director: $director }
)
}
Truy vấn tra cứu dữ liệu uỷ quyền
Bạn có thể uỷ quyền cho các đột biến Data Connect bằng cách truy vấn cơ sở dữ liệu và xác minh kết quả của truy vấn bằng biểu thức CEL. Điều này rất hữu ích khi bạn đang ghi vào một bảng và cần kiểm tra nội dung của một hàng trong một bảng khác.
Tính năng này hỗ trợ:
- Lệnh
@check
cho phép bạn đánh giá nội dung của các trường và dựa trên kết quả của quá trình đánh giá đó:- Tiếp tục tạo, cập nhật và xoá do đột biến xác định
- Sử dụng các giá trị do truy vấn trả về cho ứng dụng để thực hiện các logic khác nhau trong ứng dụng
- Lệnh
@redact
cho phép bạn bỏ qua kết quả truy vấn khỏi kết quả giao thức truyền dẫn.
Các tính năng này hữu ích cho quy trình uỷ quyền.
Sơ đồ SQL tương đương
-- 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);
Tiếp theo là gì?
- Tìm hiểu cách bảo mật các truy vấn và đột biến bằng tính năng uỷ quyền và chứng thực.
- Tìm hiểu cách gọi truy vấn và đột biến từ một SDK web, SDK Android, SDK iOS và SDK Flutter được tạo tự động.