@cypher
The @cypher
directive binds a GraphQL field to the results of a Cypher query.
This directive can be used both for properties in a type or as top level queries.
Global variables
Global variables are available for use within the Cypher statement and can be applied to the @cypher
directive.
Variable | Description | Example |
---|---|---|
|
This value is a reference to the currently resolved node, and it can be used to traverse the graph. |
|
|
This value is represented by the following TypeScript interface definition:
|
You can use the JWT in the request to return the value of the currently logged in User:
|
|
Use it to inject values into the Cypher query from the GraphQL context function. |
Inject into context:
Use in Cypher query:
|
Return values
The return value of Cypher statements must always be of the same type to which the directive is applied.
The variable must also be aliased with a name that is the same as the one passed to columnName
.
This can be the name of a node, relationship query or an alias in the RETURN
statement of the Cypher statement.
Scalar values
Cypher statements must return a value which matches the scalar type to which the directive was applied. For example:
type Query {
randomNumber: Int @cypher(statement: "RETURN rand() as result", columnName: "result")
}
Object types
When returning an object type, all fields of the type must be available in the Cypher return value. This can be achieved by either returning the entire object from the Cypher query, or returning a map of the fields which are required for the object type. Both approaches are demonstrated below:
type User {
id
}
type Query {
users: [User]
@cypher(
statement: """
MATCH (u:User)
RETURN u
""",
columnName: "u"
)
}
type User {
id
}
type Query {
users: [User] @cypher(statement: """
MATCH (u:User)
RETURN {
id: u.id
} as result
""", columnName: "result")
}
The downside of the latter approach is that you need to adjust the return object as you change your object type definition.
Input arguments
The @cypher
statement can access the query parameters by prepending $
to the parameter name. For example:
type Query {
name(value: String): String @cypher(statement: "RETURN $value AS res", columnName: "res")
}
The following GraphQL query returns the parameter value
:
query {
name(value: "Jane Smith")
}
Usage examples
The @cypher
directive can be used in different contexts, such as the ones described in this section.
On an object type field
In the example below, a field similarMovies
is bound to the Movie
type, to find other movies with an overlap of actors:
type Actor {
actorId: ID!
name: String
movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT)
}
type Movie {
movieId: ID!
title: String
description: String
year: Int
actors(limit: Int = 10): [Actor!]!
@relationship(type: "ACTED_IN", direction: IN)
similarMovies(limit: Int = 10): [Movie]
@cypher(
statement: """
MATCH (this)<-[:ACTED_IN]-(:Actor)-[:ACTED_IN]->(rec:Movie)
WITH rec, COUNT(*) AS score ORDER BY score DESC
RETURN rec LIMIT $limit
""",
columnName: "rec"
)
}
On a query type field
The following example demonstrates a query to return all of the actors in the database:
type Actor {
actorId: ID!
name: String
}
type Query {
allActors: [Actor]
@cypher(
statement: """
MATCH (a:Actor)
RETURN a
""",
columnName: "a"
)
}
On a mutation type field
The following example demonstrates a mutation using a Cypher query to insert a single actor with the specified name argument:
type Actor {
actorId: ID!
name: String
}
type Mutation {
createActor(name: String!): Actor
@cypher(
statement: """
CREATE (a:Actor {name: $name})
RETURN a
""",
columnName: "a"
)
}