Docs 菜单
Docs 主页
/ /
Atlas App Services
/ /

GraphQL 类型、解析程序和操作符

在此页面上

  • Overview
  • 标量类型
  • 文档类型
  • 字段映射
  • BSON 类型映射
  • 输入类型
  • QueryInput
  • InsertInput
  • UpdateInput
  • RelationInput
  • SortByInput
  • 查询解析程序
  • 查找单个文档
  • 查找多个文档
  • 更改解析程序
  • 插入单一文档
  • 插入多个文档
  • 更新单份文档
  • 更新多个文档
  • 更新或插入单个文档
  • 替换单份文档
  • 删除单个文档
  • 删除多个文档
  • Paginate Data

Atlas App Services 会自动为具有已定义模式的所有集合生成 GraphQL 模式。对于每个集合,App Services 均会生成以下内容:

  • 表示集合中单个文档的文档类型

  • 一组查询变更,允许您访问和操作集合中的文档。

  • 一组允许你过滤查询、修改特定字段(Field)和对结果进行排序的输入类型

注意

示例集合模式

本页中的示例演示了基于以下模式而为 movies 集合生成的值:

{
"title": "Movie",
"required": ["title"],
"properties": {
"_id": { "bsonType": "objectId" },
"title": { "bsonType": "string" },
"year": { "bsonType": "int" },
"rated": { "bsonType": "string" },
"runtime": { "bsonType": "int" },
"director": { "bsonType": "string" },
"reviews": {
"bsonType": "array",
"items": { "bsonType": "objectId" }
},
"cast": {
"bsonType": "array",
"items": { "bsonType": "string" }
}
}
}

App Services 支持所有标准 GraphQL 标量类型,并且还会生成 ObjectId 标量。

支持以下标量类型:

  • ObjectId:序列化为字符串的ObjectId

  • Booleantruefalse

  • String:UTF-8 字符序列

  • Int:有符号 32 位整数

  • Long:有符号 64 位整数

  • Float:带符号的双精度浮点值

  • DateTimeRFC3339 UTC 日期时间(例如“2020-09-01T15:38:14.918Z”)

App Services 会根据集合模式为集合中的文档生成单一 GraphQL 类型 。类型使用模式的 title 字段中设置的名称,如果没有指定 title 字段,则使用集合名称。

type Movie {
_id: ObjectId
title: String!
year: Int
rated: String
runtime: Int
director: String
cast: [String]
}

App Services 会尝试将集合模式中的字段直接映射到 GraphQL 类型中的字段。GraphQL 规范中描述的有效名称定义不支持所有可能的有效文档字段名称,因此 App Services 应用以下转换规则来确定生成的 GraphQL 类型中的字段名称:

  • 去掉不支持的字符

  • 去掉开头的数字

  • 转换为大小写混合名称

  • 省略以双下划线开头的字段(例如 __myField

GraphQL 类型系统与可在模式中使用的 BSON 类型相似,但并不相同。App Services 会自动尝试在模式中的 BSON 类型和支持的 GraphQL 类型之间进行映射。如果字段类型没有对应的 GraphQL,App Services 不会在生成的 GraphQL 文档类型中包含该字段。

下表列出了可在模式中使用的 BSON 类型及其映射到的 GraphQL 类型:

JSON/BSON 类型
GraphQL 类型
objectId
ObjectId
int
Int
long
Int
double
Float
decimal
Float
date
DateTime
timestamp
DateTime

注意

JSON 支持两种表示“无值”的类型:undefinednull。GraphQL 规范支持 null,但不支持 undefined,因此,您的应用程序将按以下方式转换 undefined 值:

  • 如果文档字段显式设置为 undefined,那么相应的 GraphQL 类型就是空对象,即 {}

  • 如果根本没有为文档定义字段名称,或者该值明确设置为null,则相应的 GraphQL 类型为null

GraphQL 使用输入类型来表示传递给查询和修改的参数。这是所有 GraphQL API 用于定义明确、类型安全的用户输入的标准方法。

QueryInput 对象定义一个或多个条件,文档必须满足这些条件才能包含在查询中。该对象可能包括文档类型的字段以及 App Services 根据每个字段的类型自动生成的任何操作符字段

  • 文档字段:如果QueryInput字段与文档类型中的字段同名,并且输入字段中指定的值与文档中字段的值相同,则 App Services 将匹配文档。

    例子

    以下查询包含一个 QueryInput 以及两个字段:ratedyearMovie 文档类型中定义了这两个字段名称,因此 App Services 会对这两个字段名称执行相等匹配。

    该查询返回 2000 年上映的所有 R 级电影的片名。

    movies(query: { rated: "R", year: 2000 }) {
    title
    }
  • 操作符字段:如果 QueryInput 字段是查询类型的有效操作符字段,那么如果操作符的值为 true,App Services 就会匹配文档。

    例子

    以下查询包含一个 QueryInput 以及两个字段:rated_inyear_gt。这两个字段均为操作符字段,因此 App Services 会对每个操作符求值以确定某一文档是否匹配。

    该查询返回 2000 年后上映的所有 G 级或 PG-13 级电影的片名。

    movies(query: { rated_in: ["G", "PG-13"], year_gt: 2000 }) {
    title
    }

比较操作符字段允许定义比精确相等更复杂的条件,例如范围查询。App Services 会根据字段类型为文档类型中每个字段生成一组比较操作符字段。每个比较操作符通常仅应用于部分字段类型,因此 App Services 仅生成有效组合的操作符字段。

对于给定文档,如果文档中的字段值相对于指定值满足操作符条件,则比较操作符字段的值为 true

比较操作符字段的形式如下:

<Field Name>_<Operator>: <Operator Value>
Operator
支持的字段类型
操作符值类型
说明
gt
Int
Float
String
ObjectId
DateTime
<Field Type>

查找字段大于指定值的文档。

例子

该查询可查找 2000 之后上映的所有电影:

movies(query: { year_gt: 2000 }) {
title
year
}
gte
Int
Float
String
ObjectId
DateTime
<Field Type>

查找该字段大于或等于指定值的文档。

例子

该查询可查找 2000 年或之后上映的所有电影:

movies(query: { year_gte: 2000 }) {
title
year
}
lt
Int
Float
String
ObjectId
DateTime
<Field Type>

查找字段小于指定值的文档。

例子

该查询可查找 2000 年或之前上映的所有电影:

movies(query: { year_lt: 2000 }) {
title
year
}
lte
Int
Float
String
ObjectId
DateTime
<Field Type>

查找相应字段小于或等于指定值的文档。

例子

该查询可查找 2000 年或之前上映的所有电影:

movies(query: { year_lte: 2000 }) {
title
year
}
ne
Int
Float
String
Boolean
ObjectId
DateTime
<Field Type>

查找该字段不等于指定值的文档。

例子

此查询查找 2000 年以外任何年份发布的所有电影:

movies(query: { year_ne: 2000 }) {
title
year
}
in
Int
Float
String
Boolean
ObjectId
DateTime
Array
[<Field Type>]

查找该字段等于指定数组中任一值的文档。如果该字段为Array,则会查找字段数组中任一值同时也包含在指定数组中的所有文档。

例子

此查询可找到所有以 Emma Stone 和 Ryan Gosling 其中一人或两人为主角的电影:

movies(query: { cast_in: ["Emma Stone", "Ryan Gosling"] }) {
title
year
}
nin
Int
Float
String
Boolean
ObjectId
DateTime
Array
[<Field Type>]

查找该字段不等于指定数组中任一值的文档。如果该字段为Array,则会查找字段数组中任一值同时也包含在指定数组中的所有文档。

例子

此查询将查找所有未被评为 G 级或 PG-13 级的电影:

movies(query: { rated_nin: ["G", "PG-13"] }) {
title
year
}

逻辑操作符字段允许您定义独立 QueryInput 对象的逻辑组合。App Services 会为所有 QueryInput 类型生成根级逻辑操作符字段。

如果所有指定的QueryInput对象的计算结果满足操作符条件,则给定文档的逻辑操作符字段的计算结果为true

逻辑操作符字段的形式如下:

<Operator>: [<QueryInput>, ...]
Operator
操作符值类型
说明
[QueryInput!]

查找与所有已提供的 QueryInput 对象匹配的文档。

例子

此查询会查找所有评级为 PG-13 播放时间少于 120 分钟的电影:

query {
movies(query: { AND: [{ rated: "PG-13" }, { runtime_lt: 120 }] }) {
title
year
}
}
[QueryInput!]

查找与任何已提供的QueryInput对象匹配的文档。

例子

此查询将查找所有被评为 G 级或 PG-13 级的电影:

query {
movies(query: { OR: [{ rated: "G" }, { rated: "PG-13" }] }) {
title
year
}
}

元素操作符字段允许您定义描述文档字段的布尔条件。 App Services 会为文档类型中的每个字段生成一组元素操作符字段。

如果文档中字段的操作符条件的计算结果与指定的布尔值匹配,则给定文档的元素操作符字段的计算结果为 true

元素运算符字段采用以下形式:

<Field Name>_<Operator>: <Operator Value>
Operator
支持的类型
操作符值类型
说明
存在
适用于所有类型
布尔

查找字段不是 null 的文档。

例子

此查询查找所有 year 字段未定义值的电影:

query {
movies(query: { year_exists: false }) {
_id
title
}
}

InsertInput 对象可定义要插入到集合中的文档。该文档必须符合 GraphQL 文档类型并包含所有必需字段。

例子

以下更改包括一个带有多个字段的InsertInput,这些字段均在Movie文档类型中定义。Movie 类型要求所有文档都有一个 title 字段,因此 InsertInput 必须包含一个字段。

此更改插入了一部名为“My Fake Film”的新电影。

insertOneMovie(input: {
title: "My Fake Film",
rated: "UNRATED",
year: 2020
}) {
title
}

UpdateInput 对象为文档中的一个或多个字段定义新值。更新后的文档包含新字段值。未指定的字段保持不变。更新后的值必须符合 GraphQL 文档类型。

例子

以下变更包括一个 UpdateInput,其中将 title 字段设置为“我的超级真实电影”。

updateOneMovie(
query: { title: "My Fake Film" }
set: { title: "My Super Real Film" }
) {
title
}

RelationInput 可为被更改文档中的关系字段定义一组新的相关文档。您可以使用 link 字段引用相关集合中已存在的文档,也可使用 create 字段将新文档插入到相关集合中。

您不能同时使用 linkcreate。如果同时指定了两者,则执行 create 操作并忽略 link

type RelationInput {
link: [ObjectId]
create: [InsertInput]
}

例子

以下变更包括可修改 reviews 字段的 UpdateInput。字段包含一个 _id 值数组,这些值代表与字段有定义关系的单独 reviews 集合中的文档。

该突变将关系设置为指向 reviews 集合中一个新创建的文档和两个现有文档。

updateOneMovie(
query: { title: "My Fake Film" }
set: {
reviews: {
link: ["", ""]
create: []
}
}
) {
title
}

SortByInput 枚举值定义了查询返回的文档的排序顺序。您可按其类型不是 objectarray 的任意根级字段进行升序和降序排序。GraphQL API 不支持嵌套排序。

App Services 为每个字段(Field)生成两个排序枚举值。每个值都是一个完全大写的标识符,结合了字段名称和排序方向( ASCDESC

例子

以下查询返回的电影按上映年份排序,最新上映的电影排在前面。

movies(sortBy: YEAR_DESC) {
title
}

App Services 会为每个集合生成两个 GraphQL 查询

  • 在集合中查找特定文档的单一查询。

  • 查找集合中所有文档的复数查询。 您可以筛选复数查询,以仅包含集合中与QueryInput匹配的文档子集。

单个文档查询字段使用与集合包含的数据类型相同的名称。其返回所查询类型的单个文档,并接受以下参数:

Parameter
类型
说明
query

可选。用于定义集合中文档的筛选器的一个对象。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。

如果不指定query参数,查询操作将匹配所有文档。

query {
movie(query: { title: "The Matrix" }) {
title
year
runtime
director
}
}

多文档查询字段使用与集合包含的数据类型相同的名称,但在类型名称后附加了一个 "s"。其返回所查询类型的文档数组,并接受以下参数:

Parameter
GraphQL 类型
说明
query

可选。用于定义集合中文档的筛选器的一个对象。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。

如果未指定 query 参数,此查询操作则会匹配所有文档。

limit
Int
可选。默认 100。查询结果集中包含的最大文档数。如果查询匹配的文档超过了设定的限制,那么只会返回匹配文档的子集。
sortBy

可选。定义查询结果集中文档排序顺序的值。您可以按任何类型不是 objectarray 的根级字段进行升序和降序排序。

sortBy值是一个完全大写的标识符,结合了字段名称和排序方向。例如:

  • 要按标题从 A 到 Z 排序,您可以使用 TITLE_ASC

  • 要按评级从高到低排序,您可以使用 RATING_DESC

如果未指定 sortBy 参数,则查询操作不能保证结果集中文档的顺序。

query {
movies(
query: { year: 2000 }
limit: 100
sortBy: TITLE_ASC
) {
title
year
runtime
director
}
}

App Services 为每个集合中的文档生成一组更改。 这些允许您插入、修改和删除一个或多个文档。

单文档插入 mutation 字段使用 insertOne<Type> 名称,其中 <Type> 是集合包含的数据类型的单数名称。它返回插入的文档并接受以下参数:

Parameter
类型
说明
data
必需。要插入到集合中的文档。如果集合模式将某一字段标记为必需,则此文档必须包含该字段的有效值。App Services 会自动将 InsertInput 对象中的 GraphQL 类型转换为相应的 BSON 类型。
mutation {
insertOneMovie(data: {
title: "Little Women"
director: "Greta Gerwig"
year: 2019
runtime: 135
}) {
_id
title
}
}

多文档插入 mutation 字段使用 insertMany<Type>s 名称,其中 <Type> 是集合包含的数据类型的单数名称。它返回插入的文档并接受以下参数:

Parameter
类型
说明
data
必需。要插入到集合中的文档数组。数组必须至少包含一个文档。如果集合模式将某一字段标记为必填字段,则每个文档都必须包含该字段的有效值。App Services 会自动将 InsertInput 对象中的 GraphQL 类型转换为集合模式中定义的相应 BSON 类型。
mutation {
insertManyMovies(data: [
{
title: "Little Women"
director: "Greta Gerwig"
year: 2019
runtime: 135
},
{
title: "1917"
director: "Sam Mendes"
year: 2019
runtime: 119
}
]) {
_id
title
}
}

单文档更新更改字段采用 updateOne<Type> 名称,其中 <Type> 为该集合所含数据类型的单数名称。它会返回已更新的文档并接受以下参数:

Parameter
类型
说明
query

可选。一个对象,它可用于配置集合中要更新的文档。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。

如果不指定 query 参数,那么突变会更新结果集中的第一个文档,很可能是最近插入的文档,但并不保证。

set
UpdateInput!
必需的。为文档中的一个或多个字段定义新值的对象。更新后的文件将包含新的字段值。未指定的字段保持不变。App Services 会自动将 UpdateInput 对象中的 GraphQL 类型转换为相应的 BSON 类型。
mutation {
updateOneMovie(
query: { title: "The Room" }
set: { runtime: 99 }
) {
_id
title
}
}

多文档更新变更字段使用名称 updateMany<Type>s,其中 <Type> 是集合包含的数据类型的单数名称。其会返回一个 UpdateManyPayload 文档,说明匹配和修改的字段数量,并接受以下参数:

Parameter
类型
说明
query

可选。一个对象,它可用于配置集合中要更新的文档。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。

如果不指定 query 参数,那么突变会更新结果集中的第一个文档,很可能是最近插入的文档,但并不保证。

set
必需的。为文档中的一个或多个字段定义新值的对象。更新后的文件将包含新的字段值。未指定的字段保持不变。App Services 会自动将 UpdateInput 对象中的 GraphQL 类型转换为相应的 BSON 类型。
mutation {
updateManyMovies(
query: { director: "Tommy Wiseau" }
set: { director: "Tom Wiseau" }
) {
matchedCount
modifiedCount
}
}

单文档 upsert 更改字段采用 upsertOne<Type> 名称,其中 <Type> 为该集合所含数据类型的单数名称。该解析程序会更新与查询参数匹配的文档;如果没有与此查询匹配的文档,则会插入新文档。它会返回已 upsert 的文档并接受以下参数:

Parameter
类型
说明
query

可选。配置要更新哪个文档的对象。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。

如果不指定query参数或没有匹配的文档,则更改将插入data参数中指定的文档。

data
必需。此query与所有现有文档均不匹配时要插入的文档。如果此query会匹配某一文档,则会用其替换所查询的文档。如果集合模式将某一字段标记为必需,则此文档必须包含该字段的有效值。App Services 会自动将 InsertInput 对象中的 GraphQL 类型转换为其相应的 BSON 类型。
mutation {
upsertOneMovie(
query: { title: "Blacksmith Scene" }
data: {
title: "Sandcastles in the Sand",
director: "Robin Scherbatsky"
runtime: 90
year: 2002
}
) {
_id
title
}
}

单文档替换更改字段使用名称 replaceOne<Type>,其中 <Type> 是集合包含的数据类型的单数名称。它返回替换的文档并接受以下参数:

Parameter
类型
说明
query

可选。一个对象,它可用于配置集合中要替换的文档。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。

如果未指定 query 参数,则此更改会替换结果集中的第一个文档,而该文档很可能(但不保证)是最近插入的文档。

data
必需。替换查询文档的文档。如果集合模式将某个字段标记为必填,则此文档必须包含该字段的有效值。App Services 会自动将InsertInput对象中的 GraphQL 类型转换为其各自的 BSON 类型。
mutation {
replaceOneMovie(
query: { title: "Blacksmith Scene" }
data: {
title: "Sandcastles in the Sand",
director: "Robin Scherbatsky"
runtime: 90
year: 2002
}
) {
_id
title
}
}

单文档删除更改字段采用 deleteOne<Type> 名称,其中 <Type> 为该集合所含数据类型的单数名称。它会返回已删除的文档并接受以下参数:

Parameter
类型
说明
query

必需。一个对象,它可用于配置集合中要删除的文档。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。

如果此query匹配多个文档,此更改则会删除结果集中的第一个文档,而该文档很可能(但不保证)是最近插入的文档。

mutation {
deleteOneMovie(query: { title: "The Room" }) {
_id
title
year
runtime
director
}
}

多文档删除更改字段使用名称deleteMany<Type>s,其中<Type>是集合包含的数据类型的单数名称。它返回一个DeleteManyPayload文档,描述已删除的文档数量并接受以下参数:

Parameter
类型
说明
query

可选。一个对象,它可用于配置集合中要删除的文档。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。

如果未指定 query 参数,则更改将删除集合中的所有文档。

mutation {
deleteManyMovies(query: { director: "Tommy Wiseau" }) {
deletedCount
}
}

您可以使用 GraphQL API 生成的模式提供的类型对查询中的数据进行分页。

Atlas GraphQL API 没有GraphQL 文档建议的那样用于分页的 offset 操作符。

相反,您可以使用生成模式的查找多个文档查询解析程序以及 querylimitsortBy 操作符对数据进行分页。

升序对数据进行分页:

query PaginateAscending(
# Do not include `previousTitle` for the first query
# in a pagination sequence.
$previousTitle: String,
$limit: Int!,
) {
movies(
query: { title_gt: $previousTitle }
limit: $limit
sortBy: TITLE_ASC
) {
title
year
runtime
director
}
}

若要按降序对数据进行分页:

query PaginateAscending(
# Do not include `nextTitle` for the first query
# in a pagination sequence.
$nextTitle: String,
$limit: Int!,
) {
movies(
query: { title_lt: $nextTitle }
limit: $limit
sortBy: TITLE_DESC
) {
title
year
runtime
director
}
}

有关在客户端应用程序中实施这种分页模式的示例,请参阅 Realm Web SDK 文档中的“分页数据”。

注意

此分页方法类似于 MongoDB 驱动程序的范围查询,如 MongoDB Server 文档中所述。

后退

验证 GraphQL 请求身份