Prisma API:查詢(Queries)

本文屬使用Prisma構(gòu)建GraphQL服務(wù)系列。

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)的idtitle

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歲的authorPost節(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、afterskip對節(jié)點(diǎn)分頁

排序

查詢某個類型的所有節(jié)點(diǎn)時,可以為每個類型的標(biāo)量字段提供orderBy參數(shù):orderBy: <field>_ASCorderBy: <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ā)布(publishedfalse)的所有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,somenone,來定義條件應(yīng)該匹配everysomenone相關(guān)節(jié)點(diǎn)。

查詢至少有一個Post已發(fā)布(publishedtrue)的所有用戶節(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)系提供了一個名稱。

組合過濾

您可以使用過濾器組合器ORAND,NOT 創(chuàng)建過濾器條件的任意邏輯組合。

使用OR,ANDNOT

查詢發(fā)布的所有Post節(jié)點(diǎn),其title包含在給定的字符串列表中:

query {
  posts(where: {
    AND: [{
      title_in: ["My biggest Adventure", "My latest Hobbies"]
    }, {
      published: true
    }]
  }) {
    id
    title
    published
  }
}

注意:OR,ANDNOT并接受一個列表作為輸入,其中每個列表項(xiàng)都是一個對象,因此需要用{}進(jìn)行包裝,例如:AND: [{title_in: ["My biggest Adventure", "My latest Hobbies"]}, {published: true}]

帶有ANDORNOT的過濾的任意組合

您可以組合甚至嵌套過濾器組合器AND,ORNOT來創(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,ORNOT之外,用于查詢類型的所有節(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é)合firstskip來達(dá)到相同的結(jié)果:

query {
  posts(
    first: 2
    skip: 1
  ) {
    id
    title
  }
}

查詢最后2個Post

query {
  posts(last: 2) {
    id
    title
  }
}

注意:您不能firstbeforelastafter混合,您還可以查詢更多的節(jié)點(diǎn),而不會出現(xiàn)錯誤消息。

請注意,共享演示群集上的每個分頁字段最多可以返回1000個節(jié)點(diǎn)。使用群集配置(the cluster configuration)的其他群集可以提高此限制。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評論 19 139
  • 本文屬使用Prisma構(gòu)建GraphQL服務(wù)系列。 概述 Prisma使用GraphQL Schema Defi...
    guog閱讀 1,531評論 0 1
  • 去年有段時間得空,就把谷歌GAE的API權(quán)威指南看了一遍,收獲頗豐,特別是在自己幾乎獨(dú)立開發(fā)了公司的云數(shù)據(jù)中心之后...
    騎單車的勛爵閱讀 21,116評論 0 41
  • 如果說我的助推鵬烈是DISC派來的天使,那你們,我親愛的組員們,你們就是那一雙雙美麗的翅膀。因?yàn)橛心銈?,凡人才能?..
    小白老師_Shirley閱讀 690評論 0 2
  • 正直君對阿糖的第一印象,是清脆好聽的少女音,帶點(diǎn)懶散含柔的小嬌氣,他無端的想到了自己窗臺上種的幾株淡紫色的風(fēng)鈴草,...
    沈貍閱讀 224評論 0 4

友情鏈接更多精彩內(nèi)容