26.4. Cypher queries

26.4.1. Send queries with parameters
26.4.2. Create a node
26.4.3. Send a query
26.4.4. Return paths
26.4.5. Nested results
26.4.6. Retrieve query metadata
26.4.7. Server errors

The Neo4j REST API allows querying with Cypher, see Part III, “Cypher Query Language”. The results are returned as a list of string headers (columns), and a data part, consisting of a list of all rows, every row consisting of a list of REST representations of the field value — Node, Relationship, Path or any simple value like String.

[Tip]Tip

In order to speed up queries in repeated scenarios, try not to use literals but replace them with parameters wherever possible in order to let the server cache query plans, see Section 26.4.1, “Send queries with parameters” for details. Also see Section 11.4, “Parameters” for where parameters can be used.

26.4.1. Send queries with parameters

Cypher supports queries with parameters which are submitted as a JSON map.

START x = node:node_auto_index(name= { startName })
MATCH path =(x-[r]-friend)
WHERE friend.name = { name }
RETURN TYPE(r)

Figure 26.3. Final Graph


Example request

  • POST http://localhost:7474/db/data/cypher
  • Accept: application/json; charset=UTF-8
  • Content-Type: application/json
{
  "query" : "start x  = node:node_auto_index(name={startName}) match path = (x-[r]-friend) where friend.name = {name} return TYPE(r)",
  "params" : {
    "startName" : "I",
    "name" : "you"
  }
}

Example response

  • 200: OK
  • Content-Type: application/json; charset=UTF-8
{
  "columns" : [ "TYPE(r)" ],
  "data" : [ [ "know" ] ]
}

26.4.2. Create a node

Create a node with a label and a property using Cypher.

CREATE (n:Person { name : { name }})
RETURN n

Figure 26.4. Final Graph


Example request

  • POST http://localhost:7474/db/data/cypher
  • Accept: application/json; charset=UTF-8
  • Content-Type: application/json
{
  "query" : "create (n:Person { name : {name} }) return n",
  "params" : {
    "name" : "Andres"
  }
}

Example response

  • 200: OK
  • Content-Type: application/json; charset=UTF-8
{
  "columns" : [ "n" ],
  "data" : [ [ {
    "outgoing_relationships" : "http://localhost:7474/db/data/node/323/relationships/out",
    "labels" : "http://localhost:7474/db/data/node/323/labels",
    "data" : {
      "name" : "Andres"
    },
    "all_typed_relationships" : "http://localhost:7474/db/data/node/323/relationships/all/{-list|&|types}",
    "traverse" : "http://localhost:7474/db/data/node/323/traverse/{returnType}",
    "self" : "http://localhost:7474/db/data/node/323",
    "property" : "http://localhost:7474/db/data/node/323/properties/{key}",
    "properties" : "http://localhost:7474/db/data/node/323/properties",
    "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/323/relationships/out/{-list|&|types}",
    "incoming_relationships" : "http://localhost:7474/db/data/node/323/relationships/in",
    "extensions" : {
    },
    "create_relationship" : "http://localhost:7474/db/data/node/323/relationships",
    "paged_traverse" : "http://localhost:7474/db/data/node/323/paged/traverse/{returnType}{?pageSize,leaseTime}",
    "all_relationships" : "http://localhost:7474/db/data/node/323/relationships/all",
    "incoming_typed_relationships" : "http://localhost:7474/db/data/node/323/relationships/in/{-list|&|types}"
  } ] ]
}

26.4.3. Send a query

A simple query returning all nodes connected to node 1, returning the node and the name property, if it exists, otherwise null:

START x = node(343)
MATCH x -[r]-> n
RETURN type(r), n.name, n.age

Figure 26.5. Final Graph


Example request

  • POST http://localhost:7474/db/data/cypher
  • Accept: application/json; charset=UTF-8
  • Content-Type: application/json
{
  "query" : "start x  = node(343) match x -[r]-> n return type(r), n.name, n.age",
  "params" : {
  }
}

Example response

  • 200: OK
  • Content-Type: application/json; charset=UTF-8
{
  "columns" : [ "type(r)", "n.name", "n.age" ],
  "data" : [ [ "know", "him", 25 ], [ "know", "you", null ] ]
}

26.4.4. Return paths

Paths can be returned together with other return types by just specifying returns.

START x = node(348)
MATCH path =(x--friend)
RETURN path, friend.name

Figure 26.6. Final Graph


Example request

  • POST http://localhost:7474/db/data/cypher
  • Accept: application/json; charset=UTF-8
  • Content-Type: application/json
{
  "query" : "start x  = node(348) match path = (x--friend) return path, friend.name",
  "params" : {
  }
}

Example response

  • 200: OK
  • Content-Type: application/json; charset=UTF-8
{
  "columns" : [ "path", "friend.name" ],
  "data" : [ [ {
    "start" : "http://localhost:7474/db/data/node/348",
    "nodes" : [ "http://localhost:7474/db/data/node/348", "http://localhost:7474/db/data/node/347" ],
    "length" : 1,
    "relationships" : [ "http://localhost:7474/db/data/relationship/198" ],
    "end" : "http://localhost:7474/db/data/node/347"
  }, "you" ] ]
}

26.4.5. Nested results

When sending queries that return nested results like list and maps, these will get serialized into nested JSON representations according to their types.

START n = node(345,344)
RETURN collect(n.name)

Figure 26.7. Final Graph


Example request

  • POST http://localhost:7474/db/data/cypher
  • Accept: application/json; charset=UTF-8
  • Content-Type: application/json
{
  "query" : "start n = node(345,344) return collect(n.name)",
  "params" : {
  }
}

Example response

  • 200: OK
  • Content-Type: application/json; charset=UTF-8
{
  "columns" : [ "collect(n.name)" ],
  "data" : [ [ [ "I", "you" ] ] ]
}

26.4.6. Retrieve query metadata

By passing in an additional GET header when you execute Cypher queries, metadata about the query will be returned, such as how many labels were added or removed by the query.

START n = node(346)
SET n:foo
REMOVE n:bar
RETURN labels(n)

Figure 26.8. Final Graph


Example request

  • POST http://localhost:7474/db/data/cypher?includeStats=true
  • Accept: application/json; charset=UTF-8
  • Content-Type: application/json
{
  "query" : "start n = node(346) set n:foo remove n:bar return labels(n)",
  "params" : {
  }
}

Example response

  • 200: OK
  • Content-Type: application/json; charset=UTF-8
{
  "columns" : [ "labels(n)" ],
  "data" : [ [ [ "foo" ] ] ],
  "stats" : {
    "relationships_created" : 0,
    "nodes_deleted" : 0,
    "relationship_deleted" : 0,
    "indexes_added" : 0,
    "properties_set" : 0,
    "constraints_removed" : 0,
    "indexes_removed" : 0,
    "labels_removed" : 1,
    "constraints_added" : 0,
    "labels_added" : 1,
    "nodes_created" : 0,
    "contains_updates" : true
  }
}

26.4.7. Server errors

Errors on the server will be reported as a JSON-formatted stacktrace and message.

START x = node(328)
RETURN x.dummy/0

Figure 26.9. Final Graph


Example request

  • POST http://localhost:7474/db/data/cypher
  • Accept: application/json; charset=UTF-8
  • Content-Type: application/json
{
  "query" : "start x = node(328) return x.dummy/0",
  "params" : {
  }
}

Example response

  • 400: Bad Request
  • Content-Type: application/json; charset=UTF-8
{
  "message": "Don\u0027t know how to Divide(Product(x,Unresolved(dummy,PropertyKey),true),Literal(0)) `0` with `null`",
  "exception": "CypherTypeException",
  "fullname": "org.neo4j.cypher.CypherTypeException",
  "stacktrace": [
    "org.neo4j.cypher.internal.commands.expressions.Arithmetics.throwTypeError(Expression.scala:98)",
    "org.neo4j.cypher.internal.commands.expressions.Arithmetics.apply(Expression.scala:107)",
    "org.neo4j.cypher.internal.pipes.ExtractPipe$$anonfun$internalCreateResults$1$$anonfun$apply$1.apply(ExtractPipe.scala:47)",
    "org.neo4j.cypher.internal.pipes.ExtractPipe$$anonfun$internalCreateResults$1$$anonfun$apply$1.apply(ExtractPipe.scala:45)",
    "scala.collection.immutable.Map$Map1.foreach(Map.scala:109)",
    "org.neo4j.cypher.internal.pipes.ExtractPipe$$anonfun$internalCreateResults$1.apply(ExtractPipe.scala:45)",
    "org.neo4j.cypher.internal.pipes.ExtractPipe$$anonfun$internalCreateResults$1.apply(ExtractPipe.scala:44)",
    "scala.collection.Iterator$$anon$11.next(Iterator.scala:328)",
    "scala.collection.Iterator$$anon$11.next(Iterator.scala:328)",
    "org.neo4j.cypher.internal.ClosingIterator$$anonfun$next$1.apply(ClosingIterator.scala:45)",
    "org.neo4j.cypher.internal.ClosingIterator$$anonfun$next$1.apply(ClosingIterator.scala:44)",
    "org.neo4j.cypher.internal.ClosingIterator.failIfThrows(ClosingIterator.scala:89)",
    "org.neo4j.cypher.internal.ClosingIterator.next(ClosingIterator.scala:44)",
    "org.neo4j.cypher.PipeExecutionResult.next(PipeExecutionResult.scala:167)",
    "org.neo4j.cypher.PipeExecutionResult.next(PipeExecutionResult.scala:34)",
    "scala.collection.Iterator$$anon$11.next(Iterator.scala:328)",
    "scala.collection.convert.Wrappers$IteratorWrapper.next(Wrappers.scala:30)",
    "org.neo4j.cypher.PipeExecutionResult$$anon$1.next(PipeExecutionResult.scala:75)",
    "org.neo4j.helpers.collection.ExceptionHandlingIterable$1.next(ExceptionHandlingIterable.java:67)",
    "org.neo4j.helpers.collection.IteratorWrapper.next(IteratorWrapper.java:47)",
    "org.neo4j.server.rest.repr.ListRepresentation.serialize(ListRepresentation.java:58)",
    "org.neo4j.server.rest.repr.Serializer.serialize(Serializer.java:75)",
    "org.neo4j.server.rest.repr.MappingSerializer.putList(MappingSerializer.java:61)",
    "org.neo4j.server.rest.repr.CypherResultRepresentation.serialize(CypherResultRepresentation.java:83)",
    "org.neo4j.server.rest.repr.MappingRepresentation.serialize(MappingRepresentation.java:41)",
    "org.neo4j.server.rest.repr.OutputFormat.assemble(OutputFormat.java:210)",
    "org.neo4j.server.rest.repr.OutputFormat.formatRepresentation(OutputFormat.java:147)",
    "org.neo4j.server.rest.repr.OutputFormat.response(OutputFormat.java:130)",
    "org.neo4j.server.rest.repr.OutputFormat.ok(OutputFormat.java:67)",
    "org.neo4j.server.rest.web.CypherService.cypher(CypherService.java:101)",
    "java.lang.reflect.Method.invoke(Method.java:606)",
    "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:132)",
    "org.neo4j.server.rest.security.SecurityFilter.doFilter(SecurityFilter.java:112)"
  ]
}