update

Using these 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 update mutations and response types should be generated:

type UpdatePostsMutationResponse {
    posts: [Post!]!
}

type UpdateUsersMutationResponse {
    users: [User!]!
}

type Mutation {
    updatePosts(
        where: PostWhere
        update: PostUpdateInput
        connect: PostConnectInput
        disconnect: PostDisconnectInput
        create: PostCreateInput
        delete: PostDeleteInput
    ): UpdatePostsMutationResponse!
    updateUsers(
        where: UserWhere
        update: UserUpdateInput
        connect: UserConnectInput
        disconnect: UserDisconnectInput
        create: UserCreateInput
        delete: UserDeleteInput
    ): UpdateUsersMutationResponse!
}

The id field cannot be updated as the @id directive has been used.

Single update

The content of a Post can be updated by executing the following GraphQL statement:

mutation {
    updatePosts(
        where: {
            id: "892CC104-A228-4BB3-8640-6ADC9F2C2A5F"
        }
        update: {
            content: "Some new content for this Post!"
        }
    ) {
        posts {
            content
        }
    }
}

This should update the post by adding the sentence "Some new content for this Post!".

Nested create using update

Instead of creating a Post with the create mutation and then connecting it to a User, you can update a User and create a Post as part of the mutation:

mutation {
    updateUsers(
        where: { name: "John Doe" }
        create: {
            posts: [
                { node: { content: "An interesting way of adding a new Post!" } }
            ]
        }
    ) {
        users {
            id
            name
            posts {
                content
            }
        }
    }
}

connectOrCreate relationships

Consider the example provided in the create page:

mutation {
  createActors(input: {
    name: "Tom Hanks",
    movies: {
      connectOrCreate: {
        where: { node: { id: "1234" } }
        onCreate: { node: { title: "Forrest Gump" } }
      }
    }
  }) {
    info {
      nodesCreated
    }
  }
}

For update operations, connectOrCreate can also be used as a top-level input for an equivalent operation:

mutation {
  updateActors(
      connectOrCreate: {
        movies: {
            where: { node: { id: "1234" } }
            onCreate: { node: { title: "Forrest Gump" } }
        }
      },
      where: { name: "Tom Hanks" }
  ) {
    info {
      nodesCreated
    }
  }
}

This operation is equivalent to the previous example.

Array methods

Array methods allow the modification of existing property arrays in update mutations within these entities:

  • Node

  • Relationship properties

  • Interfaces

For that, the following operators are available:

  • _POP: expects a single Int value as input.

  • _PUSH: conforms to the type of input defined in the type definition.

Consider the following type definitions, a Movie with a property array called tags:

type Movie {
    title: String
    tags: [String]
}

You can pop from this tags property array:

Before After
tags: ['a', 'b', 'c']
tags: ['a', 'b']
mutation {
    updateMovies (update: { tags_POP: 1 }) {
        movies {
            title
            tags
        }
    }
}

Or, for more than one property from the array:

Before After
tags: ['a', 'b', 'c']
tags: ['a']
mutation {
    updateMovies (update: { tags_POP: 2 }) {
        movies {
            title
            tags
        }
    }
}

Similarly, you can have multiple array property fields and update them in the same query:

type Movie {
    title: String
    tags: [String]
    moreTags: [String]
}

Then, you can POP from both the tags and moreTags property arrays:

Before After
tags: ['a', 'b', 'c']
moreTags: ['x', 'y', 'z']
    tags: ['a', 'b']
    moreTags: ['x']
mutation {
    updateMovies (update: { tags_POP: 1, moreTags_POP: 2 }) {
        movies {
            title
            tags
            moreTags
        }
    }
}

_PUSH

Using the same type definitions as before, you can push to the tags property array:

Before After

['some tag']

['some tag', 'another tag']

mutation {
    updateMovies (update: { tags_PUSH: "another tag" }) {
        movies {
            title
            tags
        }
    }
}

Or push multiple elements in a single update:

Before After

['some tag']

['some tag', 'another tag', 'one more tag']

mutation {
    updateMovies (update: { tags_PUSH: ["another tag", "one more tag"] }) {
        movies {
            title
            tags
        }
    }
}

Similarly, you can have multiple array property fields and update them in the same query:

type Movie {
    title: String
    tags: [String]
    moreTags: [String]
}

You can also push to both the tags and moreTags property arrays:

Before After
    tags: ['some tag']
    moreTags: []
    tags: ['some tag', 'another tag']
    moreTags ['a different tag']
mutation {
    updateMovies (update: { tags_PUSH: "another tag", moreTags_PUSH: "a different tag" }) {
        movies {
            title
            tags
            moreTags
        }
    }
}

Combined methods

It is possible to perform both a _PUSH and _POP operation in one single update mutation.

Consider the following type definitions:

type Movie {
    title: String
    tags: [String]
    moreTags: [String]
}

You can update both property arrays with either _POP or _PUSH operators at once:

Before After
    tags: ['some tag']
    moreTags: []
    tags: []
    moreTags ['a different tag']
mutation {
    updateMovies (update: { tags_POP: 1, moreTags_PUSH: "a different tag" }) {
        movies {
            title
            tags
            moreTags
        }
    }
}

Mathematical operators

Mathematical operators can be used to update numerical fields based on their original values in a single DB transaction. For that, specific operators are available on different numerical types: Int, Float, BigInt. They are supported within these entities:

  • Nodes

  • Relationship properties

  • Interfaces

For Int and BigInt types, the following operators are available:

  • _DECREMENT

  • _INCREMENT

For Float type, the following operators are available:

  • _ADD

  • _SUBTRACT

  • _MULTIPLY

  • _DIVIDE

Operators remain available as optional fields. If a mathematical operator has been used in a field not defined, it will prompt a GraphQL error.

For example, take the following GraphQL schema for a social video platform:

type Video {
  id: ID @id
  views: Int
  ownedBy: User @relationship(type: "OWN_VIDEO", properties: "OwnVideo", direction: IN)
}

type User {
  id: ID @id
  ownVideo: [Video!]! @relationship(type: "OWN_VIDEO", properties: "OwnVideo", direction: OUT)
}

type OwnVideo @relationshipProperties {
  revenue: Float
}

Suppose a user viewed a video in this platform, so that you want to increment viewersCount for that video by 1. Here is how you can do that:

mutation incrementViewCountMutation {
  updateVideos(
    where: { id: "VideoID" }
    update: { views_INCREMENT: 1 }
  ) {
    videos {
      id
      views
    }
  }
}

Now, suppose the social platform wants to reward the user with 0.01 dollars for viewing the video. To do that, you have to update the relationship property revenue:

mutation addRevenueMutation {
  updateUsers(
    where: { id: "UserID" },
    update: { ownVideo: [{ update: { edge: { revenue_ADD: 0.01 } } }] }
  ) {
    users {
      id
      ownVideoConnection {
        edges {
          revenue
        }
      }
    }
  }
}