Skip to content

Latest commit

 

History

History
1765 lines (1567 loc) · 26.9 KB

movie-tests.adoc

File metadata and controls

1765 lines (1567 loc) · 26.9 KB

Movie Test TCK

Schema

type Movie {
  _id: Int
  movieId: ID!
  title: String
  year: Int
  released: Int # was DateTime
  plot: String
  poster: String
  imdbRating: Float
  genres: [Genre] @relation(name: "IN_GENRE", direction: OUT)
  similar(first: Int = 3, offset: Int = 0): [Movie] @cypher(statement: "MATCH (this)--(:Genre)--(o:Movie) RETURN o")
  mostSimilar: Movie @cypher(statement: "RETURN this")
  degree: Int @cypher(statement: "RETURN SIZE((this)--())")
  actors(first: Int = 3, offset: Int = 0, name: String): [Actor] @relation(name: "ACTED_IN", direction:IN)
  avgStars: Float
  filmedIn: State @relation(name: "FILMED_IN", direction: OUT)
  scaleRating(scale: Int = 3): Float @cypher(statement: "RETURN $scale * this.imdbRating")
  scaleRatingFloat(scale: Float = 1.5): Float @cypher(statement: "RETURN $scale * this.imdbRating")
  actorMovies: [Movie] @cypher(statement: """
  MATCH (this)-[:ACTED_IN*2]-(other:Movie)
  RETURN other
  """)
  publishedBy: Publisher @relation(name: "PUBLISHED_BY", direction: OUT)
  ratings: [Rated] @relation(name:"RATED")
}
type Publisher {
  name: ID!
}
type Genre {
  _id: String!
  name: ID!
  movies(first: Int = 3, offset: Int = 0): [Movie] @relation(name: "IN_GENRE", direction: IN)
  highestRatedMovie: Movie @cypher(statement: "MATCH (m:Movie)-[:IN_GENRE]->(this) RETURN m ORDER BY m.imdbRating DESC LIMIT 1")
}
type State {
  _id: ID!
  name: String
}
interface Person {
  userId: ID!
  name: String
  born: _Neo4jDateTime
}
type Actor implements Person
{
  userId: ID!
  name: String
  movies: [Movie] @relation(name: "ACTED_IN", direction:OUT)
  born: _Neo4jDateTime
}
type User implements Person
{
  userId: ID!
  name: String
  rated(rating: Int): [Rated]
  friends(since: Int): [FriendOf]
  knows: [User] @relation(name: "KNOWS", direction:OUT)
  knowsPerson: [Person] @relation(name: "KNOWS", direction:OUT)
  born: _Neo4jDateTime
}
type FriendOf {
  from: User
  since: Int
  to: User
}
type Rated @relation(name:"RATED") {
  _id: ID!
  from: User
  rating: Int
  to: Movie
}
enum BookGenre {
  Mystery,
  Science,
  Math
}
type Book {
  genre: BookGenre
}
enum _MovieOrdering {
  title_desc,
  title_asc,
  year_desc,
  plot_desc
}
enum _GenreOrdering {
  name_desc,
  name_asc
}
type Query {
  Movie(_id: String, movieId: ID, title: String, year: Int, plot: String, poster: String, imdbRating: Float, first: Int, offset: Int, orderBy: _MovieOrdering): [Movie]
  MoviesByYear(year: Int): [Movie]
  MovieById(movieId: ID!): Movie
  MovieBy_Id(_id: String!): Movie
  GenresBySubstring(substring: String): [Genre] @cypher(statement: "MATCH (g:Genre) WHERE toLower(g.name) CONTAINS toLower($substring) RETURN g")
  Books: [Book]
  User: [User]
}
type Mutation {
  createGenre(name:String): Genre @cypher(statement:"CREATE (g:Genre) SET g.name = name RETURN g")
  changePerson(name: String): Person
}
# scalar DateTime

Queries

Top Level Query

GraphQL-Query
query {
  Movie {
    movieId
  }
}
Cypher Params
{}
Cypher
MATCH (movie:Movie)
RETURN movie {
	.movieId
} AS Movie

Query Single Object

GraphQL-Query
{
  MovieById(movieId: "18") {
    title
  }
}
Cypher Params
{
  "movieByIdMovieId" : "18"
}
Cypher
MATCH (movieById:Movie)
WHERE movieById.movieId = $movieByIdMovieId
RETURN movieById {
	.title
} AS MovieById LIMIT 1

Basic Query with Parameter

GraphQL-Query
{  Movie(title: "River Runs Through It, A")  {  title }  }
Cypher Params
{
  "movieTitle" : "River Runs Through It, A"
}
Cypher
MATCH (movie:Movie)
WHERE movie.title = $movieTitle
RETURN movie {
	.title
} AS Movie

Paging

GraphQL-Query
{
  Movie(title: "River Runs Through It, A", first: 1, offset: 1) {
    title
    year
  }
}
Cypher Params
{
  "movieFirst" : 1,
  "movieOffset" : 1,
  "movieTitle" : "River Runs Through It, A"
}
Cypher
MATCH (movie:Movie)
WHERE movie.title = $movieTitle
RETURN movie {
	.title,
	.year
} AS Movie SKIP $movieOffset LIMIT $movieFirst

Query Single Relation

GraphQL-Query
{
  MovieById(movieId: "3100") {
    title
    filmedIn {
      name
    }
  }
}
Cypher Params
{
  "movieByIdMovieId" : "3100"
}
Cypher
MATCH (movieById:Movie)
WHERE movieById.movieId = $movieByIdMovieId
CALL {
	WITH movieById
	OPTIONAL MATCH (movieById)-[:FILMED_IN]->(movieByIdFilmedIn:State)
	RETURN movieByIdFilmedIn {
		.name
	} AS movieByIdFilmedIn LIMIT 1
}
RETURN movieById {
	.title,
	filmedIn: movieByIdFilmedIn
} AS MovieById LIMIT 1

Query Single Object and Array of Object Relations

GraphQL-Query
{
  MovieById(movieId: "3100") {
    title
    actors {
      name
    }
    filmedIn{
      name
    }
  }
}
Cypher Params
{
  "movieByIdActorsFirst" : 3,
  "movieByIdActorsOffset" : 0,
  "movieByIdMovieId" : "3100"
}
Cypher
MATCH (movieById:Movie)
WHERE movieById.movieId = $movieByIdMovieId
CALL {
	WITH movieById
	MATCH (movieById)<-[:ACTED_IN]-(movieByIdActors:Actor)
	WITH movieByIdActors SKIP $movieByIdActorsOffset LIMIT $movieByIdActorsFirst
	RETURN collect(movieByIdActors {
		.name
	}) AS movieByIdActors
}
CALL {
	WITH movieById
	OPTIONAL MATCH (movieById)-[:FILMED_IN]->(movieByIdFilmedIn:State)
	RETURN movieByIdFilmedIn {
		.name
	} AS movieByIdFilmedIn LIMIT 1
}
RETURN movieById {
	.title,
	actors: movieByIdActors,
	filmedIn: movieByIdFilmedIn
} AS MovieById LIMIT 1

Relationship Expansion

GraphQL-Query
{
  Movie(title: "River Runs Through It, A") {
    title
    actors {
      name
    }
  }
}
Cypher Params
{
  "movieActorsFirst" : 3,
  "movieActorsOffset" : 0,
  "movieTitle" : "River Runs Through It, A"
}
Cypher
MATCH (movie:Movie)
WHERE movie.title = $movieTitle
CALL {
	WITH movie
	MATCH (movie)<-[:ACTED_IN]-(movieActors:Actor)
	WITH movieActors SKIP $movieActorsOffset LIMIT $movieActorsFirst
	RETURN collect(movieActors {
		.name
	}) AS movieActors
}
RETURN movie {
	.title,
	actors: movieActors
} AS Movie

Projection with sub-paging

GraphQL-Query
{
  Movie(title: "River Runs Through It, A") {
    title
    actors(first:3) {
      name
    }
  }
}
Cypher Params
{
  "movieActorsFirst" : 3,
  "movieActorsOffset" : 0,
  "movieTitle" : "River Runs Through It, A"
}
Cypher
MATCH (movie:Movie)
WHERE movie.title = $movieTitle
CALL {
	WITH movie
	MATCH (movie)<-[:ACTED_IN]-(movieActors:Actor)
	WITH movieActors SKIP $movieActorsOffset LIMIT $movieActorsFirst
	RETURN collect(movieActors {
		.name
	}) AS movieActors
}
RETURN movie {
	.title,
	actors: movieActors
} AS Movie

Subquery Cypher Directive

GraphQL-Query
{
  Movie {
    title
    similar {
      title
    }
  }
}
Cypher Params
{
  "movieSimilarFirst" : 3,
  "movieSimilarOffset" : 0
}
Cypher
MATCH (movie:Movie)
CALL {
	WITH movie
	CALL {
		WITH movie
		WITH movie AS this
		MATCH (this)--(:Genre)--(o:Movie) RETURN o AS movieSimilar SKIP $movieSimilarOffset LIMIT $movieSimilarFirst
	}
	RETURN collect(movieSimilar {
		.title
	}) AS movieSimilar
}
RETURN movie {
	.title,
	similar: movieSimilar
} AS Movie

Subquery Cypher Directive Paging

GraphQL-Query
{
  Movie {
    title
    similar(first:3) {
      title
    }
  }
}
Cypher Params
{
  "movieSimilarFirst" : 3,
  "movieSimilarOffset" : 0
}
Cypher
MATCH (movie:Movie)
CALL {
	WITH movie
	CALL {
		WITH movie
		WITH movie AS this
		MATCH (this)--(:Genre)--(o:Movie) RETURN o AS movieSimilar SKIP $movieSimilarOffset LIMIT $movieSimilarFirst
	}
	RETURN collect(movieSimilar {
		.title
	}) AS movieSimilar
}
RETURN movie {
	.title,
	similar: movieSimilar
} AS Movie

Handle Cypher Directive on Query Type

GraphQL-Query
{
  GenresBySubstring(substring:"Action") {
    name
    movies(first: 3) {
      title
    }
  }
}
Cypher Params
{
  "genresBySubstringMoviesFirst" : 3,
  "genresBySubstringMoviesOffset" : 0,
  "genresBySubstringSubstring" : "Action"
}
Cypher
CALL {
	WITH $genresBySubstringSubstring AS substring
	MATCH (g:Genre) WHERE toLower(g.name) CONTAINS toLower(substring) RETURN g AS genresBySubstring
}
CALL {
	WITH genresBySubstring
	MATCH (genresBySubstring)<-[:IN_GENRE]-(genresBySubstringMovies:Movie)
	WITH genresBySubstringMovies SKIP $genresBySubstringMoviesOffset LIMIT $genresBySubstringMoviesFirst
	RETURN collect(genresBySubstringMovies {
		.title
	}) AS genresBySubstringMovies
}
RETURN genresBySubstring {
	.name,
	movies: genresBySubstringMovies
} AS GenresBySubstring

Handle Cypher directive on Mutation type

GraphQL-Query
mutation someMutation {
  createGenre(name: "Wildlife Documentary") {
    name
  }
}
Cypher Params
{
  "createGenreName" : "Wildlife Documentary"
}
Cypher
CALL {
	WITH $createGenreName AS name
	CREATE (g:Genre) SET g.name = name RETURN g AS createGenre LIMIT 1
}
RETURN createGenre {
	.name
} AS createGenre

Query using Inline Fragment

GraphQL-Query
{
  Movie(title: "River Runs Through It, A") {
    title
    ratings {
      rating
      from {
        ... on User {
          name
          userId
        }
      }
    }
  }
}
Cypher Params
{
  "movieTitle" : "River Runs Through It, A"
}
Cypher
MATCH (movie:Movie)
WHERE movie.title = $movieTitle
CALL {
	WITH movie
	MATCH (movie)<-[movieRatings:RATED]-(movieRatingsFrom:User)
	RETURN collect(movieRatings {
		.rating,
		from: movieRatingsFrom {
			.name,
			.userId
		}
	}) AS movieRatings
}
RETURN movie {
	.title,
	ratings: movieRatings
} AS Movie

Deeply nested object query

GraphQL-Query
{
  Movie(title: "River Runs Through It, A") {
    title
    actors {
      name
      movies {
        title
        actors(name: "Tom Hanks") {
          name
          movies {
            title
            year
            similar(first: 3) {
              title
              year
            }
          }
        }
      }
    }
  }
}
Cypher Params
{
  "movieActorsFirst" : 3,
  "movieActorsMoviesActorsFirst" : 3,
  "movieActorsMoviesActorsMoviesSimilarFirst" : 3,
  "movieActorsMoviesActorsMoviesSimilarOffset" : 0,
  "movieActorsMoviesActorsName" : "Tom Hanks",
  "movieActorsMoviesActorsOffset" : 0,
  "movieActorsOffset" : 0,
  "movieTitle" : "River Runs Through It, A"
}
Cypher
MATCH (movie:Movie)
WHERE movie.title = $movieTitle
CALL {
	WITH movie
	MATCH (movie)<-[:ACTED_IN]-(movieActors:Actor)
	WITH movieActors SKIP $movieActorsOffset LIMIT $movieActorsFirst
	CALL {
		WITH movieActors
		MATCH (movieActors)-[:ACTED_IN]->(movieActorsMovies:Movie)
		CALL {
			WITH movieActorsMovies
			MATCH (movieActorsMovies)<-[:ACTED_IN]-(movieActorsMoviesActors:Actor)
			WHERE movieActorsMoviesActors.name = $movieActorsMoviesActorsName
			WITH movieActorsMoviesActors SKIP $movieActorsMoviesActorsOffset LIMIT $movieActorsMoviesActorsFirst
			CALL {
				WITH movieActorsMoviesActors
				MATCH (movieActorsMoviesActors)-[:ACTED_IN]->(movieActorsMoviesActorsMovies:Movie)
				CALL {
					WITH movieActorsMoviesActorsMovies
					CALL {
						WITH movieActorsMoviesActorsMovies
						WITH movieActorsMoviesActorsMovies AS this
						MATCH (this)--(:Genre)--(o:Movie) RETURN o AS movieActorsMoviesActorsMoviesSimilar SKIP $movieActorsMoviesActorsMoviesSimilarOffset LIMIT $movieActorsMoviesActorsMoviesSimilarFirst
					}
					RETURN collect(movieActorsMoviesActorsMoviesSimilar {
						.title,
						.year
					}) AS movieActorsMoviesActorsMoviesSimilar
				}
				RETURN collect(movieActorsMoviesActorsMovies {
					.title,
					.year,
					similar: movieActorsMoviesActorsMoviesSimilar
				}) AS movieActorsMoviesActorsMovies
			}
			RETURN collect(movieActorsMoviesActors {
				.name,
				movies: movieActorsMoviesActorsMovies
			}) AS movieActorsMoviesActors
		}
		RETURN collect(movieActorsMovies {
			.title,
			actors: movieActorsMoviesActors
		}) AS movieActorsMovies
	}
	RETURN collect(movieActors {
		.name,
		movies: movieActorsMovies
	}) AS movieActors
}
RETURN movie {
	.title,
	actors: movieActors
} AS Movie

Should merge an actor by the userId

GraphQL-Query
mutation {
  actor: mergeActor(userId: "1", name: "Andrea") {
    name
  }
}
Cypher Params
{
  "actorName" : "Andrea",
  "actorUserId" : "1"
}
Cypher
MERGE (actor:Actor {
	userId: $actorUserId
})
SET actor += {
	name: $actorName
}
WITH actor
RETURN actor {
	.name
} AS actor

Should auto generate add relationship mutations for arrays

GraphQL-Query
mutation {
  add: addMovieGenres(movieId: 1, genres: ["Action", "Fantasy"]) {
    title
  }
}
Cypher Params
{
  "fromMovieId" : 1,
  "toGenres" : [ "Action", "Fantasy" ]
}
Cypher
MATCH (from:Movie {
	movieId: $fromMovieId
})
MATCH (to:Genre)
WHERE to.name IN $toGenres
MERGE (from)-[:IN_GENRE]->(to)
WITH DISTINCT from AS add
RETURN add {
	.title
} AS add

Should auto generate delete relationship mutations for arrays

GraphQL-Query
mutation {
  del: deleteMovieGenres(movieId: 1, genres: ["Action", "Fantasy"]) {
    title
  }
}
Cypher Params
{
  "fromMovieId" : 1,
  "toGenres" : [ "Action", "Fantasy" ]
}
Cypher
MATCH (from:Movie {
	movieId: $fromMovieId
})
MATCH (to:Genre)
WHERE to.name IN $toGenres
MATCH (from)-[r:IN_GENRE]->(to) DELETE r
WITH DISTINCT from AS del
RETURN del {
	.title
} AS del

Should auto generate add relationship mutations

GraphQL-Query
mutation {
  add: addMoviePublishedBy(movieId: 1, publishedBy: "Company") {
    title
  }
}
Cypher Params
{
  "fromMovieId" : 1,
  "toPublishedBy" : "Company"
}
Cypher
MATCH (from:Movie {
	movieId: $fromMovieId
})
MATCH (to:Publisher {
	name: $toPublishedBy
})
MERGE (from)-[:PUBLISHED_BY]->(to)
WITH DISTINCT from AS add
RETURN add {
	.title
} AS add

Should auto generate delete relationship mutations

GraphQL-Query
mutation {
  del: deleteMoviePublishedBy(movieId: 1, publishedBy: "Company") {
    title
  }
}
Cypher Params
{
  "fromMovieId" : 1,
  "toPublishedBy" : "Company"
}
Cypher
MATCH (from:Movie {
	movieId: $fromMovieId
})
MATCH (to:Publisher {
	name: $toPublishedBy
})
MATCH (from)-[r:PUBLISHED_BY]->(to) DELETE r
WITH DISTINCT from AS del
RETURN del {
	.title
} AS del

Should auto generate add recursive relationship mutations for arrays

GraphQL-Query
mutation {
  add: addUserKnows(userId: 1, knows: [10, 23]) {
    name
  }
}
Cypher Params
{
  "fromUserId" : 1,
  "toKnows" : [ 10, 23 ]
}
Cypher
MATCH (from:User {
	userId: $fromUserId
})
MATCH (to:User)
WHERE to.userId IN $toKnows
MERGE (from)-[:KNOWS]->(to)
WITH DISTINCT from AS add
RETURN add {
	.name
} AS add

Order By

Descending, top level

GraphQL-Query
{
  Movie(year: 2010, orderBy:title_desc, first: 10) {
    title
  }
}
Cypher Params
{
  "movieFirst" : 10,
  "movieYear" : 2010
}
Cypher
MATCH (movie:Movie)
WHERE movie.year = $movieYear
RETURN movie {
	.title
} AS Movie ORDER BY movie.title DESC LIMIT $movieFirst

Descending, number

GraphQL-Query
{  Movie(orderBy:year_desc, first:10)  {  title }  }
Cypher Params
{
  "movieFirst" : 10
}
Cypher
MATCH (movie:Movie)
RETURN movie {
	.title
} AS Movie ORDER BY movie.year DESC LIMIT $movieFirst

Deeply nested orderBy

GraphQL-Query
{
  Movie(orderBy:title_desc) {
    title
    actors(orderBy:name_desc) {
      name
      movies(orderBy:[title_asc, plot_desc]) {
        title
      }
    }
  }
}
Cypher Params
{
  "movieActorsFirst" : 3,
  "movieActorsOffset" : 0
}
Cypher
MATCH (movie:Movie)
CALL {
	WITH movie
	MATCH (movie)<-[:ACTED_IN]-(movieActors:Actor)
	WITH movieActors ORDER BY movieActors.name DESC SKIP $movieActorsOffset LIMIT $movieActorsFirst
	CALL {
		WITH movieActors
		MATCH (movieActors)-[:ACTED_IN]->(movieActorsMovies:Movie)
		WITH movieActorsMovies ORDER BY movieActorsMovies.title ASC, movieActorsMovies.plot DESC
		RETURN collect(movieActorsMovies {
			.title
		}) AS movieActorsMovies
	}
	RETURN collect(movieActors {
		.name,
		movies: movieActorsMovies
	}) AS movieActors
}
RETURN movie {
	.title,
	actors: movieActors
} AS Movie ORDER BY movie.title DESC

Deeply nested query using temporal orderBy

GraphQL-Query
{
  User(orderBy: born_desc){
    name
    born {formatted}
    knows(orderBy: born_asc) {
      name
      born {formatted}
      knows(first: 2, offset: 1, orderBy: [born_asc, born_desc]) {
        name
        born {formatted}
      }
    }
  }
}
Cypher Params
{
  "userKnowsKnowsFirst" : 2,
  "userKnowsKnowsOffset" : 1
}
Cypher
MATCH (user:User)
CALL {
	WITH user
	MATCH (user)-[:KNOWS]->(userKnows:User)
	WITH userKnows ORDER BY userKnows.born ASC
	CALL {
		WITH userKnows
		MATCH (userKnows)-[:KNOWS]->(userKnowsKnows:User)
		WITH userKnowsKnows ORDER BY userKnowsKnows.born ASC, userKnowsKnows.born DESC SKIP $userKnowsKnowsOffset LIMIT $userKnowsKnowsFirst
		RETURN collect(userKnowsKnows {
			.name,
			born: {
				formatted: toString(userKnowsKnows.born)
			}
		}) AS userKnowsKnows
	}
	RETURN collect(userKnows {
		.name,
		born: {
			formatted: toString(userKnows.born)
		},
		knows: userKnowsKnows
	}) AS userKnows
}
RETURN user {
	.name,
	born: {
		formatted: toString(user.born)
	},
	knows: userKnows
} AS User ORDER BY user.born DESC

Find all relations

GraphQL-Query
{ rated(_id:1){
    rating
 }
}
Cypher Params
{
  "rated_id" : "1"
}
Cypher
MATCH ()-[rated:RATED]->()
WHERE id(rated) = toInteger($rated_id)
RETURN rated {
	.rating
} AS rated

Relations

Create relation

GraphQL-Query
mutation {
  createRated(from_userId: "1", to_movieId: "2", rating: 5) {
    _id
 }
}
Cypher Params
{
  "createRatedRating" : 5,
  "fromFrom_userId" : "1",
  "toTo_movieId" : "2"
}
Cypher
MATCH (from:User {
	userId: $fromFrom_userId
})
MATCH (to:Movie {
	movieId: $toTo_movieId
})
CREATE (from)-[createRated:RATED {
	rating: $createRatedRating
}]->(to)
WITH createRated
RETURN createRated {
	_id: id(createRated)
} AS createRated

Mutate relation

GraphQL-Query
mutation {
 updateRated(_id:1, rating: 5){
    rating
 }
}
Cypher Params
{
  "updateRatedRating" : 5,
  "updateRated_id" : 1
}
Cypher
MATCH ()-[updateRated:RATED]->()
WHERE id(updateRated) = toInteger($updateRated_id)
SET updateRated += {
	rating: $updateRatedRating
}
WITH updateRated
RETURN updateRated {
	.rating
} AS updateRated

create relation

GraphQL-Query
mutation {
 addGenreMovies(name:"Action", movies: ["m1"]){
    name
 }
}
Cypher Params
{
  "fromName" : "Action",
  "toMovies" : [ "m1" ]
}
Cypher
MATCH (from:Genre {
	name: $fromName
})
MATCH (to:Movie)
WHERE to.movieId IN $toMovies
MERGE (from)<-[:IN_GENRE]-(to)
WITH DISTINCT from AS addGenreMovies
RETURN addGenreMovies {
	.name
} AS addGenreMovies

create object with multiple labels

GraphQL-Query
mutation {
 createUser(userId:1){
    userId,
    __typename
 }
}
Cypher Params
{
  "createUserUserId" : "1",
  "createUserValidTypes" : [ "User" ]
}
Cypher
CREATE (createUser:User:Person {
	userId: $createUserUserId
})
WITH createUser
RETURN createUser {
	.userId,
	__typename: head([label IN labels(createUser) WHERE label IN $createUserValidTypes])
} AS createUser

Neo4j Data Types queryies

User born extraction

GraphQL-Query
query {
  User {
    born {
      formatted
      year
    }
  }
}
Cypher Params
{}
Cypher
MATCH (user:User)
RETURN user {
	born: {
		formatted: toString(user.born),
		year: user.born.year
	}
} AS User

User born query filter with multiple fields

GraphQL-Query
query {
  User(born: {formatted: "2015-06-24T12:50:35.556000000+01:00", year: 2015 }) {
    born {
      year
    }
  }
}
Cypher Params
{
  "userBornAnd1Year" : 2015,
  "userBornAnd2Formatted" : "2015-06-24T12:50:35.556000000+01:00"
}
Cypher
MATCH (user:User)
WHERE (user.born.year = $userBornAnd1Year
	AND user.born = datetime($userBornAnd2Formatted))
RETURN user {
	born: {
		year: user.born.year
	}
} AS User

Merge Actor with born field formatted

GraphQL-Query
mutation {
  actor: mergeActor(userId: "1", name: "Andrea", born: { formatted: "2015-06-24T12:50:35.556000000+01:00" }) {
    name
  }
}
Cypher Params
{
  "actorBorn" : {
    "formatted" : "2015-06-24T12:50:35.556000000+01:00"
  },
  "actorName" : "Andrea",
  "actorUserId" : "1"
}
Cypher
MERGE (actor:Actor {
	userId: $actorUserId
})
SET actor += {
	name: $actorName,
	born: datetime($actorBorn.formatted)
}
WITH actor
RETURN actor {
	.name
} AS actor

Create Actor with born field formatted

GraphQL-Query
mutation {
  actor: createActor(userId: "1", name: "Andrea", born: { formatted: "2015-06-24T12:50:35.556000000+01:00" }) {
    name
  }
}
Cypher Params
{
  "actorBorn" : {
    "formatted" : "2015-06-24T12:50:35.556000000+01:00"
  },
  "actorName" : "Andrea",
  "actorUserId" : "1"
}
Cypher
CREATE (actor:Actor:Person {
	userId: $actorUserId,
	name: $actorName,
	born: datetime($actorBorn.formatted)
})
WITH actor
RETURN actor {
	.name
} AS actor

Merge Actor with born field object

GraphQL-Query
mutation {
  actor: mergeActor(userId: "1", name: "Andrea", born: { year: 2018
                                                         month: 11
                                                         day: 23
                                                         hour: 10
                                                         minute: 30
                                                         second: 1
                                                         millisecond: 2
                                                         microsecond: 3
                                                         nanosecond: 4
                                                         timezone: "America/Los_Angeles" }) {
    name
  }
}
Cypher Params
{
  "actorBorn" : {
    "year" : 2018,
    "month" : 11,
    "day" : 23,
    "hour" : 10,
    "minute" : 30,
    "second" : 1,
    "millisecond" : 2,
    "microsecond" : 3,
    "nanosecond" : 4,
    "timezone" : "America/Los_Angeles"
  },
  "actorName" : "Andrea",
  "actorUserId" : "1"
}
Cypher
MERGE (actor:Actor {
	userId: $actorUserId
})
SET actor += {
	name: $actorName,
	born: datetime($actorBorn)
}
WITH actor
RETURN actor {
	.name
} AS actor

Create Actor with born field object

GraphQL-Query
mutation {
  actor: createActor(userId: "1", name: "Andrea", born: { year: 2018
                                                         month: 11
                                                         day: 23
                                                         hour: 10
                                                         minute: 30
                                                         second: 1
                                                         millisecond: 2
                                                         microsecond: 3
                                                         nanosecond: 4
                                                         timezone: "America/Los_Angeles" }) {
    name
    born {
      year
      month
    }
  }
}
Cypher Params
{
  "actorBorn" : {
    "year" : 2018,
    "month" : 11,
    "day" : 23,
    "hour" : 10,
    "minute" : 30,
    "second" : 1,
    "millisecond" : 2,
    "microsecond" : 3,
    "nanosecond" : 4,
    "timezone" : "America/Los_Angeles"
  },
  "actorName" : "Andrea",
  "actorUserId" : "1"
}
Cypher
CREATE (actor:Actor:Person {
	userId: $actorUserId,
	name: $actorName,
	born: datetime($actorBorn)
})
WITH actor
RETURN actor {
	.name,
	born: {
		year: actor.born.year,
		month: actor.born.month
	}
} AS actor

Deletion

delete node by id

GraphQL-Query
mutation{
  deleteMovie(movieId:"id"){
    title
  }
}
Cypher Params
{
  "deleteMovieMovieId" : "id"
}
Cypher
MATCH (deleteMovie:Movie {
	movieId: $deleteMovieMovieId
})
WITH deleteMovie AS toDelete, deleteMovie {
	.title
} AS deleteMovie DETACH DELETE toDelete
RETURN deleteMovie AS deleteMovie

delete node by native id

GraphQL-Query
mutation{
  deleteState(_id: 1){
    name
  }
}
Cypher Params
{
  "deleteState_id" : 1
}
Cypher
MATCH (deleteState:State)
WHERE id(deleteState) = toInteger($deleteState_id)
WITH deleteState AS toDelete, deleteState {
	.name
} AS deleteState DETACH DELETE toDelete
RETURN deleteState AS deleteState

delete relation by native id

GraphQL-Query
mutation{
  deleteRated(_id: 1){
    rating
    from {
      name
    }
  }
}
Cypher Params
{
  "deleteRated_id" : 1
}
Cypher
MATCH ()-[deleteRated:RATED]->()
WHERE id(deleteRated) = toInteger($deleteRated_id)
CALL {
	WITH deleteRated
	MATCH (from:User)-[deleteRated]->()
	WITH from LIMIT 1
	RETURN from {
		.name
	} AS from
}
WITH deleteRated AS toDelete, deleteRated {
	.rating,
	from: from
} AS deleteRated DETACH DELETE toDelete
RETURN deleteRated AS deleteRated