Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion modules/ROOT/pages/directives/custom-logic.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ type Mutation {

== `@coalesce`

When translating from GraphQL to Cypher, any instances of fields to which this directive is applied will be wrapped in a `coalesce()` function in the WHERE clause.
When translating from GraphQL to Cypher, any instances of fields to which this directive is applied will be wrapped in a `coalesce()` function in the WHERE and RETURN clause.
For more information, see link:https://neo4j.com/developer/kb/understanding-non-existent-properties-and-null-values/#_use_coalesce_to_use_a_default_for_a_null_value[Understanding non-existent properties and working with nulls].

This directive helps querying against non-existent properties in a database.
Expand Down
11 changes: 5 additions & 6 deletions modules/ROOT/pages/directives/database-mapping.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ type Movie @node {

[NOTE]
====
In version 6.x, it's not required to specify every GraphQL type representing a Neo4j node with the `@node` directive.
In the future, types without the `@node` directive will no longer be treated as Neo4j nodes.
Types without the `@node` directive are not treated as Neo4j nodes, and queries and mutations are not generated for them.
====

When not differently specified, the GraphQL type name is used as a label for the represented Neo4j node. It's possible to explicitly define the Neo4j node labels by using the parameter `labels`.
Expand Down Expand Up @@ -224,12 +223,12 @@ To add two node types, "Movie" and "Actor", and connect the two:

[source, graphql, indent=0]
----
type Movie {
type Movie @node {
title: String
actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN)
}

type Actor {
type Actor @node {
name: String
movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT)
}
Expand Down Expand Up @@ -264,12 +263,12 @@ For example, for the "ACTED_IN" relationship, add a property "roles":

[source, graphql, indent=0]
----
type Movie {
type Movie @node {
title: String
actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn")
}

type Actor {
type Actor @node {
name: String
movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn")
}
Expand Down
2 changes: 0 additions & 2 deletions modules/ROOT/pages/directives/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@ Particularly useful for types that are not correctly pluralized or are non-Engli
| xref::/directives/indexes-and-constraints.adoc#_fulltext[`@fulltext`]
| Indicates that there should be a fulltext index inserted into the database for the specified Node and its properties.

| xref::/directives/indexes-and-constraints.adoc#_unique[`@unique`]
| Indicates that there should be a uniqueness constraint in the database for the fields that it is applied to.

| xref::/directives/indexes-and-constraints.adoc#_vector_index_search[`@vector`]
| Perform a vector index search on your database either based by passing in a vector index or a search phrase.
Expand Down
4 changes: 2 additions & 2 deletions modules/ROOT/pages/directives/indexes-and-constraints.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ For example:
[source, graphql, indent=0]
----
input FullTextInput {
indexName: String
queryName: String
indexName: String!
queryName: String!
fields: [String]!
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ type Actor {
name: String!
age: Int
actedIn(where: MovieWhere, sort: [MovieSort!]!, limit: Int, offset: Int, directed: Boolean = true): [Movie!]!
actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}
----
Expand Down Expand Up @@ -57,14 +56,13 @@ Now the type `Actor` looks like this:
type Actor {
name: String!
actedIn(where: MovieWhere, sort: [MovieSort!]!, limit: Int, offset: Int, 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`

There are several nested operations available for every field created using the `@relationship` directive. These are `create`, `connect`, `disconnect`, `connectOrCreate`, and `delete`.
There are several nested operations available for every field created using the `@relationship` directive. These are `create`, `connect`, `disconnect`, and `delete`.

However, these operations are not always needed.
The `@relationship` directive allows you to define which operations should be available for a relationship by using the argument `nestedOperations`.
Expand All @@ -82,15 +80,14 @@ enum NestedOperations {
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]
nestedOperations: [NestedOperations!]! = [CREATE, UPDATE, DELETE, CONNECT, DISCONNECT]
aggregate: Boolean! = true
) on FIELD_DEFINITION
----
Expand All @@ -99,19 +96,25 @@ directive @relationship(

*Configure aggregation*

From the previous type definitions, the type `Actor` produced is:
From the previous type definitions, the type related to `Actor` produced are:

[source, graphql, indent=0]
----
type Actor {
name: String!
actedIn(where: MovieWhere, sort: [MovieSort!]!, limit: Int, offset: Int, directed: Boolean = true): [Movie!]!
actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}

type ActorActedInConnection {
edges: [ActorActedInRelationship!]!
totalCount: Int!
pageInfo: PageInfo!
aggregate: ActorMovieActedInAggregateSelection!
}
----

Note that the relationship field `actedIn` produces the operation field `actedInAggregate`, which allows aggregations on that relationship.
Note that the relationship field `actedIn` produces the operation field `aggregate` in the type `ActorActedInConnection`, which allows aggregations on that relationship.
It is possible to configure this behavior by passing the argument aggregate on the `@relationship` directive:

[source, graphql, indent=0]
Expand All @@ -128,15 +131,14 @@ type Actor @node {
}
----

In this case, as the argument `aggregate` was passed as false, the type `Actor` produced is:
In this case, as the argument `aggregate` was passed as false, the type `ActorActedInConnection` produced is:

[source, graphql, indent=0]
----
type Actor {
name: String!
age: Int
actedIn(where: MovieWhere, sort: [MovieSort!]!, limit: Int, offset: Int, directed: Boolean = true): [Movie!]!
actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
type ActorActedInConnection {
edges: [ActorActedInRelationship!]!
totalCount: Int!
pageInfo: PageInfo!
}
----

Expand All @@ -155,7 +157,6 @@ enum NestedOperations {
DELETE
CONNECT
DISCONNECT
CONNECT_OR_CREATE
}
----

Expand All @@ -176,7 +177,7 @@ type Movie @node {
type Actor @node {
name: String!
age: Int
actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, nestedOperations: [UPDATE, DELETE, CONNECT, DISCONNECT, CONNECT_OR_CREATE])
actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, nestedOperations: [UPDATE, DELETE, CONNECT, DISCONNECT])
}
----

Expand Down Expand Up @@ -242,14 +243,13 @@ Aggregations, however, are available on both:

[source, graphql, indent=0]
----
type MovieAggregateSelection {
count: Int!
description: StringAggregateSelectionNullable!
title: StringAggregateSelectionNonNullable!
type MovieAggregateNode {
title: StringAggregateSelection!
description: StringAggregateSelection!
}
----

In case you want to remove the `description` field from `MovieAggregateSelection`, you need to change the `onAggregate` value to `false`:
In case you want to remove the `description` field from `MovieAggregateNode`, you need to change the `onAggregate` value to `false`:

[source, graphql, indent=0]
----
Expand All @@ -270,7 +270,6 @@ From the previous type definitions, the type `Actor` produced is:
type Actor {
name: String!
actedIn(where: MovieWhere, sort: [MovieSort!]!, limit: Int, offset: Int, directed: Boolean = true): [Movie!]!
actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}
----
Expand Down Expand Up @@ -300,12 +299,17 @@ Generate the type `Actor`:
----
type Actor {
name: String!
actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}

type ActorActedInConnection {
aggregate: ActorMovieActedInAggregateSelection!
}
----

Note how `actedInAggregate` is not affected by the argument `onAggregate`.
To disable the generation of `actedInAggregate`, see the `aggregate` argument of the directive xref::/schema-configuration/field-configuration.adoc#_relationship[`@relationship`].
Note how the `actedInConnection` field is generated but `aggregate` is still present on the `ActorActedInConnection` type, and not affected by the argument `onAggregate`.

To disable the generation of the `aggregate` field on , see the `aggregate` argument of the directive xref::/schema-configuration/field-configuration.adoc#_relationship[`@relationship`].

== `@settable`

Expand Down Expand Up @@ -351,7 +355,7 @@ input MovieCreateInput {
}

input MovieUpdateInput {
title: String
title: StringScalarMutations
}
----

Expand Down Expand Up @@ -387,12 +391,12 @@ input ActorCreateInput {
}

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

This means `actedIn` can be updated on an update, but it is no longer available on `create`` operations.
This means `actedIn` can be updated on an update, but it is no longer available on `create` operations.

== `@filterable`

Expand Down Expand Up @@ -437,41 +441,17 @@ input MovieWhere {
OR: [MovieWhere!]
AND: [MovieWhere!]
NOT: MovieWhere
title_EQ: 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
title: StringScalarFilters
actors: ActorRelationshipFilters
actorsConnection: MovieActorsConnectionFilters
}


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
title: StringScalarAggregationFilters
}
----

Expand Down Expand Up @@ -507,33 +487,16 @@ input MovieWhere {
OR: [MovieWhere!]
AND: [MovieWhere!]
NOT: MovieWhere
title_EQ: String
title_IN: [String!]
title_CONTAINS: String
title_STARTS_WITH: String
title_ENDS_WITH: String
title: StringScalarFilters
}

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
title: StringScalarAggregationFilters
}

----

As shown by the previous inputs fields, the `actors` field is not available for filtering on both value and aggregation filters.
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,29 @@ type Actor @node {
extend schema @query(read: true, aggregate: false)
----

**Query**
This configuration disables all top-level aggregation operations for the `Movie` and `Actor` types, while still allowing read operations.

* `movies`
* [.line-through]#`moviesAggregate`#
* `moviesConnection`
* `actors`
* [.line-through]#`actorsAggregate`#
* `actorsConnection`
[source, graphql, indent=0]
----
type Query {
moviesConnection(first: Int, after: String, where: MovieWhere, sort: [MovieSort!]): MoviesConnection!
movies(where: MovieWhere, limit: Int, offset: Int, sort: [MovieSort!]): [Movie!]!
actorsConnection(first: Int, after: String, where: ActorWhere, sort: [ActorSort!]): ActorsConnection!
actors(where: ActorWhere, limit: Int, offset: Int, sort: [ActorSort!]): [Actor!]!
}

type MoviesConnection {
edges: [MovieEdge!]!
totalCount: Int!
pageInfo: PageInfo!
}

type ActorsConnection {
edges: [ActorEdge!]!
totalCount: Int!
pageInfo: PageInfo!
}
----

**Invalid schema usage**

Expand Down
Loading