31.6. How to use (individual commands)

The shell is modeled after Unix shells like bash that you use to walk around your local file system. It has some of the same commands, like cd and ls. When you first start the shell (see instructions above), you will get a list of all the available commands. Use man <command> to get more info about a particular command. Some notes:


Single line comments, which will be ignored, can be made by using the prefix //. Example:

// This is a comment

Current node/relationship and path

You have a current node/relationship and a "current path" (like a current working directory in bash) that you’ve traversed so far. When the shell first starts you are not positioned on any entity, but you can cd your way through the graph (check your current path at any time with the pwd command). cd can be used in different ways:

  • cd <node-id> will traverse one relationship to the supplied node id. The node must have a direct relationship to the current node.
  • cd -a <node-id> will do an absolute path change, which means the supplied node doesn’t have to have a direct relationship to the current node.
  • cd -r <relationship-id> will traverse to a relationship instead of a node. The relationship must have the current node as either start or end point. To see the relationship ids use the ls -vr command on nodes.
  • cd -ar <relationship-id> will do an absolute path change which means the relationship can be any relationship in the graph.
  • cd .. will traverse back one step to the previous location, removing the last path item from your current path (pwd).
  • cd start (only if your current location is a relationship). Traverses to the start node of the relationship.
  • cd end (only if your current location is a relationship). Traverses to the end node of the relationship.

Listing the contents of a node/relationship

List contents of the current node/relationship (or any other node) with the ls command. Please note that it will give an empty output if the current node/relationship has no properties or relationships (for example in the case of a brand new graph). ls can take a node id as argument as well as filters, see Section 31.4, “Filters” and for information about how to specify direction see Section 31.3, “Enum options”. Use man ls for more info.

Creating nodes and relationships

You create new nodes by connecting them with relationships to the current node. For example, mkrel -t A_RELATIONSHIP_TYPE -d OUTGOING -c will create a new node (-c) and draw to it an OUTGOING relationship of type A_RELATIONSHIP_TYPE from the current node. If you already have two nodes which you’d like to draw a relationship between (without creating a new node) you can do for example, mkrel -t A_RELATIONSHIP_TYPE -d OUTGOING -n <other-node-id> and it will just create a new relationship between the current node and that other node.

Setting, renaming and removing properties

Property operations are done with the set, mv and rm commands. These commands operates on the current node/relationship.

Use set <key> <value>, optionally with the -t option (for value type), to set a property. Supports every type of value that Neo4j supports. Examples of a property of type int:

$ set -t int age 29

And an example of setting a double[] property:

$ set -t double[] my_values [1.4,12.2,13]

Example of setting a String property containing a JSON string:

mkrel -c -d i -t DOMAIN_OF --np "{'app':'foobar'}"
  • rm <key> removes a property.
  • mv <key> <new-key> renames a property from one key to another.

Deleting nodes and relationships

Deletion of nodes and relationships is done with the rmnode and rmrel commands. rmnode can delete nodes, if the node to be deleted still has relationships they can also be deleted by supplying -f option. rmrel can delete relationships, it tries to ensure connectedness in the graph, but relationships can be deleted regardless with the -f option. rmrel can also delete the node on the other side of the deleted relationship if it’s left with no more relationships, see -d option.

Environment variables

The shell uses environment variables a-la bash to keep session information, such as the current path and more. The commands for this mimics the bash commands export and env. For example you can at anytime issue a export STACKTRACES=true command to set the STACKTRACES environment variable to true. This will then result in stacktraces being printed if an exception or error should occur. Allowed values are all parseable JSON strings, so maps {age:10,name:"Mattias"} and arrays [1,2,3] are also supported.

Variables can also be assigned to each other. E.g. a=b will result in a containing the value of b.

This becomes especially interesting as all shell variables are automatically passed to cypher statements as parameters. That makes it easy to query for certain start nodes or create nodes and relationships with certain provided properties (as maps).

Values are removed by setting them to null or an empty value. List environment variables using env

Executing groovy/python scripts

The shell has support for executing scripts, such as Groovy and Python (via Jython). As of now the scripts (*.groovy, *.py) must exist on the server side and gets called from a client with for example, gsh --renamePerson 1234 "Mathias" "Mattias" --doSomethingElse where the scripts renamePerson.groovy and doSomethingElse.groovy must exist on the server side in any of the paths given by the GSH_PATH environment variable (defaults to .:src:src/script). This variable is like the java classpath, separated by a :. The python/jython scripts can be executed with the jsh in a similar fashion, however the scripts have the .py extension and the environment variable for the paths is JSH_PATH.

When writing the scripts assume that there’s made available an args variable (a String[]) which contains the supplied arguments. In the case of the renamePerson example above the array would contain ["1234", "Mathias", "Mattias"]. Also please write your outputs to the out variable, such as out.println( "My tracing text" ) so that it will be printed at the shell client instead of the server.


You can traverse the graph with the trav command which allows for simple traversing from the current node. You can supply which relationship types (w/ regex matching) and optionally direction as well as property filters for matching nodes. In addition to that you can supply a command line to execute for each match. An example: trav -o depth -r KNOWS:both,HAS_.*:incoming -c "ls $n". Which means traverse depth first for relationships with type KNOWS disregarding direction and incoming relationships with type matching HAS_.\* and do a ls <matching node> for each match. The node filtering is supplied with the -f option, see Section 31.4, “Filters”. See Section 31.3, “Enum options” for the traversal order option. Even relationship types/directions are supplied using the same format as filters.

Query with Cypher

You can use Cypher to query the graph. For that, use the match or start command. You can also use create statements to create nodes and relationships and use the cypher VERSION prefix to select a certain cypher version.


Cypher queries need to be terminated by a semicolon ;.

Cypher commands are given all shell variables as parameters and the special self parameter for the current node or relationship.

  • start n = node(0) return n; will give you a listing of the node with ID 0
  • cypher 1.9 start n = node(0) return n; will execute the query with Cypher version 1.9
  • START n = node({self}) MATCH (n)-[:KNOWS]->(friend) RETURN friend; will return the nodes connected to the current node.
  • START n=node({me}) CREATE (me)-[r:KNOWS]->(friend {props}); will create the friend and the relationship according to the variables available.

Listing Indexes and Constraints

The schema command allows to list all existing indexes and constraints together with their current status.


This command does not list legacy indexes. For working with legacy indexes, please see the section called “Legacy Indexing”.

List all indexes and constraints:


List indexes or constraints on :Person nodes for the property name:

schema -l :Person -p name

The schema command supports the following parameters:

  • -l :Label only list indexes or constraints for the given label :Label
  • -p propertyKey only list indexes or constraints for the given property key propertyKey
  • -v if an index is in the FAILED state, print a verbose error cause if available

Indexes and constraints can be created or removed using Cypher or the Java Core API. They are updated automatically whenever the graph is changed. See Section 3.7, “Schema” for more information.

Legacy Indexing

It’s possible to query and manipulate legacy indexes via the index command.

Example: index -i persons name (will index the name for the current node or relationship in the "persons" legacy index).

  • -g will do exact lookup in the legacy index and display hits. You can supply -c with a command to be executed for each hit.
  • -q will ask the legacy index a query and display hits. You can supply -c with a command to be executed for each hit.
  • --cd will change current location to the hit from the query. It’s just a convenience for using the -c option.
  • --ls will do a listing of the contents for each hit. It’s just a convenience for using the -c option.
  • -i will index a key-value pair into a legacy index for the current node/relationship. If no value is given the property value for that key for the current node is used as value.
  • -r will remove a key-value pair (if it exists) from a legacy index for the current node/relationship. Key and value are optional.
  • -t will set the legacy index type to work with, for example index -t Relationship --delete friends will delete the friends relationship index.


It is useful to be able to test changes, and then being able to commit or rollback said changes.

Transactions can be nested. With a nested transaction, a commit does not write any changes to disk, except for the top level transaction. A rollback, however works regardless of the level of the transaction. It will roll back all open transactions.

  • begin transaction Starts a transaction.
  • commit Commits a transaction.
  • rollback Rollbacks all open transactions.

Dumping the database or Cypher statement results

[Caution]Experimental feature

The dump command has incomplete functionality. It might not work for your use case or data size.

As a simple way of exporting a database or a subset of it, the dump command converts the graph of a Cypher result or the whole database into a single Cypher create statement.


  • dump dumps the whole database as single cypher create statement
  • dump START n=node({self}) MATCH p=(n)-[r:KNOWS*]->(m) RETURN n,r,m; dumps the transitive friendship graph of the current node.
  • neo4j-shell -path db1 -c 'dump MATCH p=(n:Person {name:"Mattias"})-[r:KNOWS]->(m) RETURN p;' | neo4j-shell -path db2 -file - imports the subgraph of the first database (db1) into the second (db2)

Example Dump Scripts

 # create a new node and go to it
 neo4j-sh (?)$ mknode --cd --np "{'name':'Neo'}"

 # create a relationship
 neo4j-sh (Neo,0)$ mkrel -c -d i -t LIKES --np "{'app':'foobar'}"

 # Export the cypher statement results
 neo4j-sh (Neo,0)$ dump MATCH (n)-[r]-(m) WHERE n = {self} return n,r,m;
 create (_0 {`name`:"Neo"})
 create (_1 {`app`:"foobar"})
 create _1-[:`LIKES`]->_0
 # create an index
 neo4j-sh (?)$ create index on :Person(name);
 | No data returned. |
 Indexes added: 1
 726 ms

 # create one labeled node and a relationship
 neo4j-sh (?)$ create (m:Person:Hacker {name:'Mattias'}), (m)-[:KNOWS]->(m);
 | No data returned. |
 Nodes created: 1
 Relationships created: 1
 Properties set: 1
 Labels added: 2
 372 ms

 # Export the whole database including indexes
 neo4j-sh (?)$ dump
 create index on :`Person`(`name`)
 create (_0:`Person`:`Hacker` {`name`:"Mattias"})
 create _0-[:`KNOWS`]->_0