Neo4j Server Extension for Streaming Cypher Results
Latest commit 1dfffaa Jul 6, 2012 @jexp Update master
Failed to load latest commit information.

Streaming Cypher

Just put the jar (streaming-cypher-extension-1.7.M03.jar) into neo4j-server/plugins and add this to the conf/ file


Then you can issue

curl -d'{"query":"start n=node(*) return n"}' -H accept:application/json -H content-type:application/json http://localhost:7474/streaming/cypher

to query the graph and stream the results.

Note, for rendering the existing format of the Neo4j-REST API (without the additional discoverable URLs) use mode=compat:

curl -d'{"query":"start n=node(*) return n"}' -H accept:application/json;mode=compat -H content-type:application/json http://localhost:7474/streaming/cypher

A pretty printing result is acquired by adding `format=pretty to the Accept Header.

curl -d'{"query":"start n=node(*) return n"}' -H accept:application/json;format=pretty -H content-type:application/json http://localhost:7474/streaming/cypher

A sample Parser/Client implementation is in org.neo4j.server.extension.streaming.cypher.CypherResultReader

The format is for a query like:

start n=node(*) match p=n-[r]-m return  n as first,r as rel,m as second, as name, as foo,ID(n) as id, p as path , NODES(p) as all

// columns
// rows is an array of array of objects each object is { type : value }
// number of rows
// full runtime including streaming all the results

header params/websocket format (in protocol field)

mode=none mode=compact mode=compat


websocket protocol

  • array of commands
  • each command is: [opcode, selector, data]


  • selector: id, [ids], ref, { index:key : value}, { index : query}, * (selector after opcode or as start, end for relationships, traversals etc.)

  • ref is a lookup mechanism during command execution (in a context)

  • data is a map or a list of maps depending on command

  • streaming results

    function init() { ws = new WebSocket("ws://localhost:8080/command");ws.onmessage = function(evt) { console.log(;}} ws.send(JSON.stringify([["ADD_NODES",null,{data:{name:"foo"},ref:"foo", unique: { index: "test", key: "name", value:"foo"}}],["GET_NODES","*",null]]))


  • ADD_NODES : data is single or array of { data : {props}, ref : "ref", index : {index: key: value:} | [{}], unique: {index: key: value:}}

  • ADD_RELS : data is single or array of { data : {props}, ref : "ref",type:"type", start: selector, end : selector, index : {index: key: value: } | [{}], unique: {index: key: value:}}

  • DELETE_NODES : uses selector , if data is { force : true } it also deletes the relationships

  • DELETE_RELS : uses selector

  • UPDATE_NODES, UPDATE_RELS : uses selector, data is array or single of { data : {props}, ref : "ref", index : {index: [key:] [value:] [old:]}}, null values delete properties and index entries, old index value will be removed

  • CYPHER : data is { query : "query" , [params : { params}], useContext: true, mergeResult : true } useContext -> merges current context with params, merges cypher result with context