GraphQL 类型、解析程序和操作符
在此页面上
Overview
Atlas App Services 会自动为具有已定义模式的所有集合生成 GraphQL 模式。对于每个集合,App Services 均会生成以下内容:
注意
示例集合模式
本页中的示例演示了基于以下模式而为 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
标量。
支持以下标量类型:
文档类型
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
)
BSON 类型映射
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 支持两种表示“无值”的类型:undefined
和 null
。GraphQL 规范支持 null
,但不支持 undefined
,因此,您的应用程序将按以下方式转换 undefined
值:
如果文档字段显式设置为
undefined
,那么相应的 GraphQL 类型就是空对象,即{}
。如果根本没有为文档定义字段名称,或者该值明确设置为
null
,则相应的 GraphQL 类型为null
。
输入类型
GraphQL 使用输入类型来表示传递给查询和修改的参数。这是所有 GraphQL API 用于定义明确、类型安全的用户输入的标准方法。
QueryInput
QueryInput
对象定义一个或多个条件,文档必须满足这些条件才能包含在查询中。该对象可能包括文档类型的字段以及 App Services 根据每个字段的类型自动生成的任何操作符字段。
文档字段:如果
QueryInput
字段与文档类型中的字段同名,并且输入字段中指定的值与文档中字段的值相同,则 App Services 将匹配文档。例子
以下查询包含一个
QueryInput
以及两个字段:rated
和year
。Movie
文档类型中定义了这两个字段名称,因此 App Services 会对这两个字段名称执行相等匹配。该查询返回 2000 年上映的所有 R 级电影的片名。
movies(query: { rated: "R", year: 2000 }) { title } 操作符字段:如果
QueryInput
字段是查询类型的有效操作符字段,那么如果操作符的值为true
,App Services 就会匹配文档。例子
以下查询包含一个
QueryInput
以及两个字段:rated_in
和year_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 之后上映的所有电影:
| ||||
gte | Int Float String ObjectId DateTime | <Field Type> | 查找该字段大于或等于指定值的文档。 例子该查询可查找 2000 年或之后上映的所有电影:
| ||||
lt | Int Float String ObjectId DateTime | <Field Type> | 查找字段小于指定值的文档。 例子该查询可查找 2000 年或之前上映的所有电影:
| ||||
lte | Int Float String ObjectId DateTime | <Field Type> | 查找相应字段小于或等于指定值的文档。 例子该查询可查找 2000 年或之前上映的所有电影:
| ||||
ne | Int Float String Boolean ObjectId DateTime | <Field Type> | 查找该字段不等于指定值的文档。 例子此查询查找 2000 年以外任何年份发布的所有电影:
| ||||
in | Int Float String Boolean ObjectId DateTime Array | [<Field Type>] | 查找该字段等于指定数组中任一值的文档。如果该字段为 例子此查询可找到所有以 Emma Stone 和 Ryan Gosling 其中一人或两人为主角的电影:
| ||||
nin | Int Float String Boolean ObjectId DateTime Array | [<Field Type>] | 查找该字段不等于指定数组中任一值的文档。如果该字段为 例子此查询将查找所有未被评为 G 级或 PG-13 级的电影:
|
逻辑操作符字段
逻辑操作符字段允许您定义独立 QueryInput
对象的逻辑组合。App Services 会为所有 QueryInput
类型生成根级逻辑操作符字段。
如果所有指定的QueryInput
对象的计算结果满足操作符条件,则给定文档的逻辑操作符字段的计算结果为true
。
逻辑操作符字段的形式如下:
<Operator>: [<QueryInput>, ...]
Operator | 操作符值类型 | 说明 | ||||||
---|---|---|---|---|---|---|---|---|
和 | [QueryInput!] | 查找与所有已提供的 例子此查询会查找所有评级为 PG-13 且播放时间少于 120 分钟的电影:
| ||||||
或 | [QueryInput!] | 查找与任何已提供的 例子此查询将查找所有被评为 G 级或 PG-13 级的电影:
|
元素操作符字段
元素操作符字段允许您定义描述文档字段的布尔条件。 App Services 会为文档类型中的每个字段生成一组元素操作符字段。
如果文档中字段的操作符条件的计算结果与指定的布尔值匹配,则给定文档的元素操作符字段的计算结果为 true
。
元素运算符字段采用以下形式:
<Field Name>_<Operator>: <Operator Value>
Operator | 支持的类型 | 操作符值类型 | 说明 | ||||||
---|---|---|---|---|---|---|---|---|---|
存在 | 适用于所有类型 | 布尔 | 查找字段不是 例子此查询查找所有
|
InsertInput
InsertInput
对象可定义要插入到集合中的文档。该文档必须符合 GraphQL 文档类型并包含所有必需字段。
例子
以下更改包括一个带有多个字段的InsertInput
,这些字段均在Movie
文档类型中定义。Movie
类型要求所有文档都有一个 title
字段,因此 InsertInput
必须包含一个字段。
此更改插入了一部名为“My Fake Film”的新电影。
insertOneMovie(input: { title: "My Fake Film", rated: "UNRATED", year: 2020 }) { title }
UpdateInput
UpdateInput
对象为文档中的一个或多个字段定义新值。更新后的文档包含新字段值。未指定的字段保持不变。更新后的值必须符合 GraphQL 文档类型。
例子
以下变更包括一个 UpdateInput
,其中将 title
字段设置为“我的超级真实电影”。
updateOneMovie( query: { title: "My Fake Film" } set: { title: "My Super Real Film" } ) { title }
RelationInput
RelationInput
可为被更改文档中的关系字段定义一组新的相关文档。您可以使用 link
字段引用相关集合中已存在的文档,也可使用 create
字段将新文档插入到相关集合中。
您不能同时使用 link
和 create
。如果同时指定了两者,则执行 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
SortByInput
枚举值定义了查询返回的文档的排序顺序。您可按其类型不是 object
或 array
的任意根级字段进行升序和降序排序。GraphQL API 不支持嵌套排序。
App Services 为每个字段(Field)生成两个排序枚举值。每个值都是一个完全大写的标识符,结合了字段名称和排序方向( ASC
或DESC
。
例子
以下查询返回的电影按上映年份排序,最新上映的电影排在前面。
movies(sortBy: YEAR_DESC) { title }
查询解析程序
App Services 会为每个集合生成两个 GraphQL 查询:
在集合中查找特定文档的单一查询。
查找集合中所有文档的复数查询。 您可以筛选复数查询,以仅包含集合中与
QueryInput
匹配的文档子集。
查找单个文档
单个文档查询字段使用与集合包含的数据类型相同的名称。其返回所查询类型的单个文档,并接受以下参数:
Parameter | 类型 | 说明 |
---|---|---|
query | 可选。用于定义集合中文档的筛选器的一个对象。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。 如果不指定 |
query { movie(query: { title: "The Matrix" }) { title year runtime director } }
查找多个文档
多文档查询字段使用与集合包含的数据类型相同的名称,但在类型名称后附加了一个 "s"
。其返回所查询类型的文档数组,并接受以下参数:
Parameter | GraphQL 类型 | 说明 |
---|---|---|
query | 可选。用于定义集合中文档的筛选器的一个对象。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。 如果未指定 | |
limit | Int | 可选。默认 100 。查询结果集中包含的最大文档数。如果查询匹配的文档超过了设定的限制,那么只会返回匹配文档的子集。 |
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 | [InsertInput!]! | 必需。要插入到集合中的文档数组。数组必须至少包含一个文档。如果集合模式将某一字段标记为必填字段,则每个文档都必须包含该字段的有效值。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 | 可选。一个对象,它可用于配置集合中要更新的文档。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。 如果不指定 | |
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 | 可选。一个对象,它可用于配置集合中要更新的文档。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。 如果不指定 | |
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 | 可选。配置要更新哪个文档的对象。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。 如果不指定 | |
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 | 可选。一个对象,它可用于配置集合中要替换的文档。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。 如果未指定 | |
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 | 必需。一个对象,它可用于配置集合中要删除的文档。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。 如果此 |
mutation { deleteOneMovie(query: { title: "The Room" }) { _id title year runtime director } }
删除多个文档
多文档删除更改字段使用名称deleteMany<Type>s
,其中<Type>
是集合包含的数据类型的单数名称。它返回一个DeleteManyPayload
文档,描述已删除的文档数量并接受以下参数:
Parameter | 类型 | 说明 |
---|---|---|
query | 可选。一个对象,它可用于配置集合中要删除的文档。该对象可能会指定数据类型中的一个或多个字段,且须包含每个字段的值。此查询会匹配包含指定字段值的所有文档。 如果未指定 |
mutation { deleteManyMovies(query: { director: "Tommy Wiseau" }) { deletedCount } }
Paginate Data
您可以使用 GraphQL API 生成的模式提供的类型对查询中的数据进行分页。
Atlas GraphQL API 没有像 GraphQL 文档建议的那样用于分页的 offset
操作符。
相反,您可以使用生成模式的查找多个文档查询解析程序以及 query
、limit
和 sortBy
操作符对数据进行分页。
按升序对数据进行分页:
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 文档中所述。