create
Using the following type definitions:
type Post {
id: ID! @id
content: String!
creator: User! @relationship(type: "HAS_POST", direction: IN)
}
type User {
id: ID! @id
name: String
posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT)
}
These create
mutations and response types should be generated:
type CreatePostsMutationResponse {
posts: [Post!]!
}
type CreateUsersMutationResponse {
users: [User!]!
}
type Mutation {
createPosts(input: [PostCreateInput!]!): CreatePostsMutationResponse!
createUsers(input: [UsersCreateInput!]!): CreateUsersMutationResponse!
}
Note that the CreateInput
types closely mirror the object type definitions.
This allows you to create not only the type in question, but to recurse down and perform further operations on related types in the same mutation.
The |
Single create
A single User
can be created by executing the following GraphQL statement:
mutation {
createUsers(input: [
{
name: "John Doe"
}
]) {
users {
id
name
}
}
}
This should create a User
with name "John Doe", and that name plus the autogenerated ID should be returned.
Nested create
A User
and an initial Post
can be created by executing the following:
mutation {
createUsers(input: [
{
name: "John Doe"
posts: {
create: [
{
node: {
content: "Hi, my name is John!"
}
}
]
}
}
]) {
users {
id
name
posts {
id
content
}
}
}
}
This creates a User
with name "John Doe" and an introductory post.
Both should be returned with their autogenerated IDs.
You can perform similar and complementary actions by using the |
connectOrCreate
relationships
If a related node has the @unique
directive defined, connectOrCreate
can be used in a nested create
to perform a MERGE
operation on the related node.
This will create a new relationship and the related node if it doesn’t exist yet.
Consider the following type definitions:
type Actor {
name: String!
movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT)
}
type Movie {
title: String
id: ID! @id @unique
actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN)
}
Because a movie ID is unique, connectOrCreate
can be used in an Actor
mutation to ensure the movie exists in the database before connecting.
Note that only @unique
or @id
fields can be used in where
:
mutation {
createActors(input: {
name: "Tom Hanks",
movies: {
connectOrCreate: {
where: { node: { id: "1234" } }
onCreate: { node: { title: "Forrest Gump" } }
}
}
}) {
info {
nodesCreated
}
}
}
This will ensure that a movie with ID 1234 exists and it is connected to "Tom Hanks"
. If the movie does not exist, it will be created with the title "Forrest Gump"
. Note that if the movie with the given ID already exists, it will be connected to it, regardless of the title.
CREATE
optimization
With the create
operations, there is no limit on how many nodes can be created at once.
However, there is a known performance issue for large batch sizes.
The Neo4j GraphQL Library contains an optimization feature designed to mitigate it, but it does not work in the following scenarios:
-
A field is populated using the directive
@populated_by
. -
The
connect
orconnectOrCreate
operation is used. -
Interface and union types are present in the mutation.