Prisma API提供兩種查詢:
- 對象查詢:獲取某個對象類型的單個或多個節(jié)點(diǎn)
- 連接查詢:暴露高級功能,如聚合(aggregation)和 Relay compliant connections實(shí)現(xiàn)強(qiáng)大的分頁模型
在使用Prisma API時,以下功能也是值得留意:
- 分層查詢:跨關(guān)系提取數(shù)據(jù)
- 查詢參數(shù):允許過濾,排序,分頁等
通常,Prisma API服務(wù)是基于其數(shù)據(jù)模型生成的。要查看Prisma API中的操作,可以使用GraphQL Playground。
在下文中,我們將看看基于如下數(shù)據(jù)模型的Prisma服務(wù)示例查詢:
type Post {
id: ID! @unique
title: String!
published: Boolean!
author: User!
}
type User {
id: ID! @unique
age: Int
email: String! @unique
name: String!
accessRole: AccessRole
posts: [Post!]!
}
enum AccessRole {
USER
ADMIN
}
對象查詢
我們可以使用對象查詢來獲取單個節(jié)點(diǎn)或某個對象類型的節(jié)點(diǎn)列表。
在這里,我們使用posts查詢來獲取Post節(jié)點(diǎn)的列表。在響應(yīng)中,只包含每個Post節(jié)點(diǎn)的id和title:
query {
posts {
id
title
}
}
我們還可以使用post查詢來查詢特定的Post節(jié)點(diǎn)。請注意,我們使用where參數(shù)來選擇節(jié)點(diǎn):
query {
post(where: {
id: "cixnen24p33lo0143bexvr52n"
}) {
id
title
published
}
}
由于User是我們數(shù)據(jù)模型中的另一種類型,因此users是另一種可用查詢。再次,我們可以使用where參數(shù)為返回的User指定條件。在這個例子中,我們篩選所有age大于18歲的User節(jié)點(diǎn):
query {
users(where: {
age_gt: 18
}) {
id
name
}
}
這也適用于所有關(guān)系,在這里我們提取那些age大于18歲的author的Post節(jié)點(diǎn):
query {
posts(where: {
author: {
age_gt: 18
}
}) {
id
title
author {
name
age
}
}
}
連接查詢(Connection queries)
對象查詢直接返回節(jié)點(diǎn)列表。在特殊情況下或使用高級功能時,使用連接查詢是首選選項(xiàng)。它們是中繼連接(Relay connections)的延伸(并且完全符合)。中繼連接的核心思想是提供關(guān)于數(shù)據(jù)圖中邊緣的元信息。例如,每條邊不僅可以訪問關(guān)于相應(yīng)對象(節(jié)點(diǎn))的信息,還可以與允許實(shí)現(xiàn)強(qiáng)大分頁的游標(biāo)相關(guān)聯(lián)。
在這里,我們使用postsConnection查詢獲取所有Post節(jié)點(diǎn)。注意我們也要求每個邊的cursor:
# Fetch all posts
query {
postsConnection {
edges {
cursor
node {
id
title
}
}
}
}
連接查詢還通過aggregate顯示聚合功能:
# Count all posts with a title containing 'GraphQL'
query {
postsConnection(where: {
title_contains: "GraphQL"
}) {
aggregate {
count
}
}
}
跨關(guān)系查詢數(shù)據(jù)
數(shù)據(jù)模型中的每個可用關(guān)系都會為它所連接的兩個模型的查詢添加一個新字段。
在這里,我們正在使用posts字段獲取特定的User以及所有相關(guān)的Post節(jié)點(diǎn):
query {
user(where: {
id: "cixnekqnu2ify0134ekw4pox8"
}) {
id
name
posts {
id
published
}
}
}
嵌套的user.posts的行為與頂級posts查詢完全相同,因?yàn)樗试S您指定您感興趣的Post類型的哪些字段。
查詢參數(shù)
在整個Prisma API中,您會發(fā)現(xiàn)可以提供的查詢參數(shù)以進(jìn)一步控制查詢響應(yīng)。查詢參數(shù)有:
- 使用
orderBy按節(jié)點(diǎn)任何字段值排序 - 通過使用
where的標(biāo)量或關(guān)系過濾器在查詢中選擇節(jié)點(diǎn) - 查詢字符串中使用
first、before、last、after和skip對節(jié)點(diǎn)分頁
排序
查詢某個類型的所有節(jié)點(diǎn)時,可以為每個類型的標(biāo)量字段提供orderBy參數(shù):orderBy: <field>_ASC 或 orderBy: <field>_DESC。
按照title升序排序:
query {
posts(orderBy: title_ASC) {
id
title
published
}
}
按published降序排序:
query {
posts(orderBy: published_DESC) {
id
title
published
}
}
注意:您所排序的字段不必在實(shí)際查詢中選擇。如果您沒有指定順序,則響應(yīng)會自動按
id字段升序排列。
當(dāng)前版本不支持按多個字段或關(guān)聯(lián)字段排序
過濾
查詢某個類型的所有節(jié)點(diǎn)時,可以根據(jù)需要為where參數(shù)提供不同的參數(shù)以約束返回的數(shù)據(jù)??捎眠x項(xiàng)取決于所討論類型上定義的標(biāo)量和關(guān)系字段。
單個過濾
如果您只向where參數(shù)提供一個參數(shù),則查詢響應(yīng)將只包含遵守此約束的節(jié)點(diǎn)。多個過濾器可以使用AND、OR進(jìn)行組合,詳見下文。
1. 按值過濾
過濾查詢響應(yīng)的最簡單方法是提供一個字段值進(jìn)行過濾。
查詢尚未發(fā)布(published為false)的所有Post節(jié)點(diǎn):
query {
posts(where: {
published: false
}) {
id
title
published
}
}
2. 高級過濾
根據(jù)您要過濾的字段的類型,您可以使用不同的高級標(biāo)準(zhǔn)來篩選查詢響應(yīng)。
查詢title在給定字符串列表中的所有Post節(jié)點(diǎn):
query {
posts(where: {
title_in: ["My biggest Adventure", "My latest Hobbies"]
}) {
id
title
published
}
}
注意:您必須提供一個列表作為
<field> _in參數(shù):title_in: ["My biggest Adventure", "My latest Hobbies"]。
關(guān)系過濾
對于一對一關(guān)系,可以通過將相關(guān)參數(shù)嵌套在相關(guān)節(jié)點(diǎn)中來定義條件。
查詢其作者角色為USER的所有Post節(jié)點(diǎn):
query {
posts(where: {
author: {
accessRole: USER
}
}) {
title
}
}
對于多對多關(guān)系,可以使用三個附加參數(shù):every,some和none,來定義條件應(yīng)該匹配every,some和none相關(guān)節(jié)點(diǎn)。
查詢至少有一個Post已發(fā)布(published為true)的所有用戶節(jié)點(diǎn):
query {
users(where: {
posts_some: {
published: true
}
}) {
id
posts {
published
}
}
}
關(guān)系過濾器也可用于一對一或多對多關(guān)系的嵌套參數(shù)。
查詢不喜歡ADMIN角色作者的帖子的所有用戶節(jié)點(diǎn):
query {
users(where: {
likedPosts_none: {
author: {
accessRole: ADMIN
}
}
}) {
name
}
}
注意:
likePosts不是上述數(shù)據(jù)模型的一部分,但可以通過將相應(yīng)的字段添加到User類型中:likedPosts: [Post!]! @relation(name: "LikedPosts")。請注意,為避免歧義,我們還為關(guān)系提供了一個名稱。
組合過濾
您可以使用過濾器組合器OR,AND,NOT 創(chuàng)建過濾器條件的任意邏輯組合。
使用OR,AND和NOT
查詢發(fā)布的所有Post節(jié)點(diǎn),其title包含在給定的字符串列表中:
query {
posts(where: {
AND: [{
title_in: ["My biggest Adventure", "My latest Hobbies"]
}, {
published: true
}]
}) {
id
title
published
}
}
注意:
OR,AND和NOT并接受一個列表作為輸入,其中每個列表項(xiàng)都是一個對象,因此需要用{}進(jìn)行包裝,例如:AND: [{title_in: ["My biggest Adventure", "My latest Hobbies"]}, {published: true}]
帶有AND,OR和NOT的過濾的任意組合
您可以組合甚至嵌套過濾器組合器AND,OR和NOT來創(chuàng)建過濾條件的任意邏輯組合。
查詢所有已發(fā)布并且其title在給定字符串列表中的Post節(jié)點(diǎn),或者查詢我們提供的特定id:
query($published: Boolean) {
posts(where: {
OR: [{
AND: [{
title_in: ["My biggest Adventure", "My latest Hobbies"]
}, {
published: $published
}]
}, {
id: "cixnen24p33lo0143bexvr52n"
}]
}) {
id
title
published
}
}
請注意,我們是如何將
AND組合器嵌套在OR組合器中的,與id值過濾器處于同一級別。
除了過濾器組合器AND,OR和NOT之外,用于查詢類型的所有節(jié)點(diǎn)的可用過濾器參數(shù)取決于類型的字段及其類型。
目前,既沒有標(biāo)量列表過濾器( scalar list filters)也沒有JSON過濾器(JSON filters)可用。在GITHUB的各個特征請求中加入討論。
分頁
查詢特定對象類型的所有節(jié)點(diǎn)時,可以提供允許您對查詢響應(yīng)進(jìn)行分頁的參數(shù)。
分頁允許您同時請求一定數(shù)量的節(jié)點(diǎn)。您可以通過節(jié)點(diǎn)向前或向后尋找并提供可選的起始節(jié)點(diǎn):
- 向前,使用
first;使用指定起始節(jié)點(diǎn)的after - 向后,使用
last,使用指定起始節(jié)點(diǎn)的before
通過提供skip參數(shù),您還可以跳過任意數(shù)量的節(jié)點(diǎn),無論您正在尋找哪個方向。
考慮一個博客,其中只有3個Post節(jié)點(diǎn)顯示在首頁。要查詢第一頁:
query {
posts(first: 3) {
id
title
}
}
在第一個Post節(jié)點(diǎn)之后查詢前兩個Post節(jié)點(diǎn):
query {
posts(
first: 2
after: "cixnen24p33lo0143bexvr52n"
) {
id
title
}
}
我們可以通過結(jié)合first和skip來達(dá)到相同的結(jié)果:
query {
posts(
first: 2
skip: 1
) {
id
title
}
}
查詢最后2個Post:
query {
posts(last: 2) {
id
title
}
}
注意:您不能
first與before或last于after混合,您還可以查詢更多的節(jié)點(diǎn),而不會出現(xiàn)錯誤消息。
請注意,共享演示群集上的每個分頁字段最多可以返回1000個節(jié)點(diǎn)。使用群集配置(the cluster configuration)的其他群集可以提高此限制。