字段配置

如果您需要从 GraphQL 对象类型或 GraphQL 输入对象类型中删除字段,请考虑以下类型定义

type Movie {
    title: String!
    description: String
}

type Actor {
    name: String!
    age: Int
    actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT)
}

它生成类型 Actor

type Actor {
  name: String!
  age: Int
  actedIn(where: MovieWhere, options: MovieOptions, directed: Boolean = true): [Movie!]!
  actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
  actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}

通过使用指令 @selectable@settable@filterable@relationship,可以控制这些字段的公开方式。例如,要隐藏选择集中的 age 字段,可以使用 @selectable 指令

type Movie {
    title: String!
    description: String
}

type Actor {
    name: String!
    age: Int @selectable(onRead: false, onAggregate: false)
    actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT)
}

现在 Actor 类型如下所示

type Actor {
  name: String!
  actedIn(where: MovieWhere, options: MovieOptions, directed: Boolean = true): [Movie!]!
  actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
  actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}

@relationship

对于使用 @relationship 指令创建的每个字段,都有多个嵌套操作可用。这些是 createconnectdisconnectconnectOrCreatedelete

但是,这些操作并不总是需要。@relationship 指令允许您使用参数 nestedOperations 定义哪些操作应可用于关系。

此外,@relationship 指令会导致为嵌套聚合添加字段。可以使用 aggregate 参数禁用这些字段。

定义

enum NestedOperations {
    CREATE
    UPDATE
    DELETE
    CONNECT
    DISCONNECT
    CONNECT_OR_CREATE
}

directive @relationship(
    type: String!
    queryDirection: RelationshipQueryDirection! = DEFAULT_DIRECTED
    direction: RelationshipDirection!
    properties: String
    nestedOperations: [NestedOperations!]! = [CREATE, UPDATE, DELETE, CONNECT, DISCONNECT, CONNECT_OR_CREATE]
    aggregate: Boolean! = true
) on FIELD_DEFINITION

用法

配置聚合

从前面的类型定义中,生成的 Actor 类型是

type Actor {
  name: String!
  actedIn(where: MovieWhere, options: MovieOptions, directed: Boolean = true): [Movie!]!
  actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
  actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}

请注意,关系字段 actedIn 生成了操作字段 actedInAggregate,它允许对该关系进行聚合。可以通过在 @relationship 指令上传递参数 aggregate 来配置此行为

type Movie {
    title: String!
    description: String
}

type Actor {
    name: String!
    age: Int
    actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, aggregate: false)
}

在这种情况下,由于参数 aggregate 被传递为 false,因此生成的 Actor 类型是

type Actor {
  name: String!
  age: Int
  actedIn(where: MovieWhere, options: MovieOptions, directed: Boolean = true): [Movie!]!
  actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}

配置嵌套操作

库生成的大部分架构都需要支持嵌套操作。这些由指令 @relationship 启用,如 @relationship → 插入数据 中所述。

可用的嵌套操作是

enum NestedOperations {
    CREATE
    UPDATE
    DELETE
    CONNECT
    DISCONNECT
    CONNECT_OR_CREATE
}

默认情况下,@relationship 在定义时启用所有这些操作。要仅启用其中的一些操作,您必须传递参数 nestedOperations,指定所需的操作。

禁用嵌套创建

要禁用嵌套 CREATE 操作,请将初始类型定义更改为

type Movie {
    title: String!
    description: String
}

type Actor {
    name: String!
    age: Int
    actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, nestedOperations: [UPDATE, DELETE, CONNECT, DISCONNECT, CONNECT_OR_CREATE])
}

由于 CREATE 操作不存在于 nestedOperations 参数数组中,因此无法再从 Actor 类型创建电影。

禁用所有嵌套操作

如果不需要嵌套操作,则可以通过传递空数组来禁用所有嵌套操作

type Movie {
    title: String!
    description: String
}

type Actor {
    name: String!
    age: Int
    actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, nestedOperations: [])
}

@selectable

此指令设置字段在查询和聚合中的可用性。它有两个参数

  • onRead:如果禁用,则此字段在查询和订阅中不可用。

  • onAggregate:如果禁用,则此字段不可用于聚合。

定义

"""Instructs @neo4j/graphql to generate this field for selectable fields."""
directive @selectable(onRead: Boolean! = true, onAggregate: Boolean! = true) on FIELD_DEFINITION

用法

使用以下定义

type Movie {
    title: String!
    description: String @selectable(onRead: false, onAggregate: true)
}

结果架构中的 Movie 类型如下所示

type Movie {
    title: String!
}

这意味着无法查询描述,无论是在顶层还是嵌套级别。但是,聚合在两者中都可用

type MovieAggregateSelection {
    count: Int!
    description: StringAggregateSelectionNullable!
    title: StringAggregateSelectionNonNullable!
}

如果您想从 MovieAggregateSelection 中删除 description 字段,则需要将 onAggregate 值更改为 false

type Movie {
    title: String!
    description: String @selectable(onRead: false, onAggregate: false)
}

@selectable 与关系一起使用

此指令可以与关系字段一起使用。

从前面的类型定义中,生成的 Actor 类型是

type Actor {
  name: String!
  actedIn(where: MovieWhere, options: MovieOptions, directed: Boolean = true): [Movie!]!
  actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
  actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}

这意味着 actedIn 字段可以从同名的生成字段 actedIn 和字段 actedInConnection 查询。为了避免这种情况,需要使用指令 @selectable。例如,这些类型定义

type Movie {
    title: String!
    description: String
}

type Actor {
    name: String!
    actedIn: [Movie!]!
        @relationship(type: "ACTED_IN", direction: OUT)
        @selectable(onRead: false, onAggregate: false)
}

生成 Actor 类型

type Actor {
  name: String!
  actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
}

请注意 actedInAggregate 如何不受参数 onAggregate 的影响。要禁用 actedInAggregate 的生成,请参阅 @relationship 指令的 aggregate 参数。

@settable

此指令设置输入字段在创建和更新变异中的可用性。它有两个参数

  • onCreate:如果禁用,则此字段在创建操作中不可用。

  • onUpdate:如果禁用,则此字段在更新操作中不可用。

定义

"""Instructs @neo4j/graphql to generate this input field for mutation."""
directive @settable(onCreate: Boolean! = true, onUpdate: Boolean! = true) on FIELD_DEFINITION

用法

使用此定义

type Movie {
    title: String!
    description: String @settable(onCreate: true, onUpdate: false)
}

type Actor {
    name: String!
    actedIn: [Movie!]!
        @relationship(type: "ACTED_IN", direction: OUT)
}

将生成以下输入字段

input MovieCreateInput {
    description: String
    title: String!
}

input MovieUpdateInput {
    title: String
}

这意味着描述可以在创建时设置,但在更新操作中不可用。

@settable 与关系一起使用

此指令可以与关系字段一起使用。当以这种方式禁用字段上的操作时,该关系将不再在顶层操作中可用。例如

type Movie {
    title: String!
    description: String
}

type Actor {
    name: String!
    actedIn: [Movie!]!
        @relationship(type: "ACTED_IN", direction: OUT)
        @settable(onCreate: false, onUpdate: true)
}

将生成以下输入字段

input ActorCreateInput {
  name: String!
}

input ActorUpdateInput {
  name: String
  actedIn: [ActorActedInUpdateFieldInput!]
}

这意味着 actedIn 可以更新,但它不再在 create` 操作中可用。

@filterable

此指令定义为应用此指令的字段生成的过滤器。它有两个参数

  • byValue:如果禁用,则此字段不会生成值过滤器。

  • byAggregate:如果禁用,则此字段不会生成聚合过滤器。

定义

"""Instructs @neo4j/graphql to generate filters for this field."""
directive @filterable(byValue: Boolean! = true, byAggregate: Boolean! = true) on FIELD_DEFINITION

用法

使用此定义

type Movie {
    title: String!
    description: String @filterable(byValue: false, byAggregate: false)
    actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN)
}

type Actor {
    name: String!
    actedIn: [Movie!]!
        @relationship(type: "ACTED_IN", direction: OUT)
}

将生成以下输入字段

input MovieWhere {
  OR: [MovieWhere!]
  AND: [MovieWhere!]
  NOT: MovieWhere
  title: String
  title_IN: [String!]
  title_CONTAINS: String
  title_STARTS_WITH: String
  title_ENDS_WITH: String
  actorsAggregate: MovieActorsAggregateInput
  actors_ALL: ActorWhere
  actors_NONE: ActorWhere
  actors_SINGLE: ActorWhere
  actors_SOME: ActorWhere
  actorsConnection_ALL: MovieActorsConnectionWhere
  actorsConnection_NONE: MovieActorsConnectionWhere
  actorsConnection_SINGLE: MovieActorsConnectionWhere
  actorsConnection_SOME: MovieActorsConnectionWhere
}

input ActorActedInNodeAggregationWhereInput {
  AND: [ActorActedInNodeAggregationWhereInput!]
  OR: [ActorActedInNodeAggregationWhereInput!]
  NOT: ActorActedInNodeAggregationWhereInput
  title_AVERAGE_LENGTH_EQUAL: Float
  title_LONGEST_LENGTH_EQUAL: Int
  title_SHORTEST_LENGTH_EQUAL: Int
  title_AVERAGE_LENGTH_GT: Float
  title_LONGEST_LENGTH_GT: Int
  title_SHORTEST_LENGTH_GT: Int
  title_AVERAGE_LENGTH_GTE: Float
  title_LONGEST_LENGTH_GTE: Int
  title_SHORTEST_LENGTH_GTE: Int
  title_AVERAGE_LENGTH_LT: Float
  title_LONGEST_LENGTH_LT: Int
  title_SHORTEST_LENGTH_LT: Int
  title_AVERAGE_LENGTH_LTE: Float
  title_LONGEST_LENGTH_LTE: Int
  title_SHORTEST_LENGTH_LTE: Int
}

如生成的输入字段所示,description 字段在值和聚合过滤器中都不可用于过滤。

@filterable 与关系一起使用

此指令可以与关系字段一起使用。当以这种方式禁用字段上的操作时,该关系将不再在顶层操作中可用。例如

type Movie {
    title: String!
    description: String @filterable(byValue: false, byAggregate: false)
    actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) @filterable(byValue: false, byAggregate: false)
}

type Actor {
    name: String!
    actedIn: [Movie!]!
        @relationship(type: "ACTED_IN", direction: OUT)

}

将生成以下输入字段

input MovieWhere {
  OR: [MovieWhere!]
  AND: [MovieWhere!]
  NOT: MovieWhere
  title: String
  title_IN: [String!]
  title_CONTAINS: String
  title_STARTS_WITH: String
  title_ENDS_WITH: String
}

input ActorActedInNodeAggregationWhereInput {
  AND: [ActorActedInNodeAggregationWhereInput!]
  OR: [ActorActedInNodeAggregationWhereInput!]
  NOT: ActorActedInNodeAggregationWhereInput
  title_AVERAGE_LENGTH_EQUAL: Float
  title_LONGEST_LENGTH_EQUAL: Int
  title_SHORTEST_LENGTH_EQUAL: Int
  title_AVERAGE_LENGTH_GT: Float
  title_LONGEST_LENGTH_GT: Int
  title_SHORTEST_LENGTH_GT: Int
  title_AVERAGE_LENGTH_GTE: Float
  title_LONGEST_LENGTH_GTE: Int
  title_SHORTEST_LENGTH_GTE: Int
  title_AVERAGE_LENGTH_LT: Float
  title_LONGEST_LENGTH_LT: Int
  title_SHORTEST_LENGTH_LT: Int
  title_AVERAGE_LENGTH_LTE: Float
  title_LONGEST_LENGTH_LTE: Int
  title_SHORTEST_LENGTH_LTE: Int
}

如前面的输入字段所示,actors 字段在值和聚合过滤器中都不可用于过滤。