シェル

Neo4j Wiki から

If you're just looking for an example try the Shell Matrix Example, otherwise read on. This is like a manual for the Shell.

Neo4j shell is a command-line shell for browsing the graph, much like how the Unix shell along with commands like cd, ls and pwd can be used to browse your local file system. It consists of two parts: a lightweight client that sends commands via RMI and a server that processes those commands and sends the result back to the client. It's a nice tool for development and debugging. This guide will show you how to get it going!


目次

[edit] The shell server

There are two parts to installing and enabling the remote shell server. First, you need to make sure that the shell jar file is on the classpath when you start up your Neo4j instance.

[edit] Include the shell jar

  • If you don't use maven, go to http://neo4j.org/download and download the latest release of the neo4j-shell-SOME_VERSION.jar file. Then add it to your -classpath command line switch, or to your ant-enabled lib folder, or right-click and add-to-build-path in Eclipse or however you add jar files to your classpath in your environment.
  • If you use maven (and have added the Neo4j m2 repository to the <repositories>-tag in your pom as outlined in the Getting Started Guide): add the following to your pom.xml:
<dependency> 
	<groupId>org.neo4j</groupId>
	<artifactId>neo4j-shell</artifactId>
	<version>SOME_VERSION</version> <!-- latest stable version, as of 2010-08-30, is 1.1 -->
</dependency>

[edit] Enabling the shell server

The shell server is enabled from the Configuration Settings of the Neo4j kernel by simply adding:

enable_remote_shell = true

For default port or:

enable_remote_shell = port=1234

For specifying a custom port. The Neo4j server enables the shell by default.

[edit] Starting the shell

There are two ways to start the shell, either by connecting to a remote shell server or by pointing it to a Neo4j store path.

[edit] Connecting to a remote shell server

To start the shell and connect to a running remote shell server, run:

java -jar neo4j-shell-<version>.jar 

Alternatively supplying -port and -name options if depending on how the remote shell server was enabled. Then you'll get the shell prompt like this:

neo4j-sh (0)$

[edit] Pointing the shell to a path

To start the shell by just pointing it to a Neo4j store path you run the shell jar file. Given that the right neo4j-kernel-<version>.jar and jta jar files are in the same path as your neo4j-shell-<version>.jar file you run it with:

$ java -jar neo4j-shell-<version>.jar -path path/to/neo4j-db

Else you can try the packaged shell distribution,

/../neo4j-shell-[version]-standalone/bin/neo4j-shell -path [path/to/db]

or include those jar files manually, f.ex. with:

$ java -cp neo4j-shell-<version>.jar:neo4j-kernel-<version>.jar:geronimo-a_1.1_spec-1.1.1.jar
       org.neo4j.shell.StartClient -path path/to/graphdb 

[edit] Read-only mode

By issuing the -readonly switch when starting the shell with a store path, no changes will be made to the database during the session.

[edit] Run command then exit

It is possible to tell the shell to just start, execute a command and then exit. This opens up for uses of background jobs and also handling of huge output of f.ex. an ls command where you then could pipe the output to less or another reader of your choice, or even to a file. So some examples of usage:

$ java -jar neo4j-shell.jar -c "cd -a 24 && set name Mattias"

Or

$ java -jar neo4j-shell.jar -c "trav -r KNOWS" | less

[edit] Notes about passing options and arguments

Passing options and arguments to your commands is very similar to many CLI commands in an *nix environment. Options are prefixed with a - and can contain one or more options. Some options expect a value to be associated with it. Arguments are string values which aren't prefixed with -. Let's look at ls as an example:

ls -r -d OUTGOING -v 12345 will make a verbose listing of node 12345's relationships which have the direction OUTGOING. The node id, 12345, is an argument to ls which tells it to do the listing on that node instead of the current node (see pwd command). However a shorter version of this can be written:

ls -rdv OUTGOING 12345. Here all three options are written together after a single '-' prefix. Even though the d is in the middle it gets associated with the OUTGOING value. The reason for this is that the ls command doesn't expect any values associated with the r or v options, hence it can infer that the OUTGOING value refers the d option.

[edit] Notes about enum options

Some options expects a value which is one of the values in an enum, f.ex. direction (-d in ls) where there's INCOMING, OUTGOING and BOTH. All such values can be supplied in an easier way. It's enough that you write the start of the value and the interpreter will find what you really meant. So if we look at ls again you can supply the -d option value like: out, in, i or even INCOMING.

[edit] Notes about filters

Some commands makes use of filters for varying purposes. F.ex. -f in ls and in trav. A filter is supplied as a json object (w/ or w/o the surrounding {} brackets and where both keys and values can contain regular expressions for a more flexible matching. An example of a filter could be .*url.*:http.*neo4j.*,name:Neo4j. The filter option is also accompanied by the options -i and -l which stands for ignore case (ignore casing of the characters) and loose matching (it's considered a match even if the filter value just matches a part of the compared value, not necessarily the entire value). So for a case-insensitive, loose filter you can supply a filter with -f -i -l or -fil for short.

[edit] Notes about node titles

To make it easier to navigate your graph the shell can display a title for each node, f.ex. in a ls -r command. It will display the relationships as well as the nodes on the other side of the relationships. The title is displayed together with each node and its best suited property value from a list of property keys.

F.ex. if you're standing on a node which has two KNOWS relationships to other nodes it'd be difficult to know which friend is which. The title feature addresses this by reading a list of property keys and grabbing the first existing property value of those keys and displays it as a title for the node. So you may specify a list (with or without regular expressions), f.ex: name,title.*,caption and the title for each node will be the property value of the first existing key in that list. The list is defined by the client (you) using the TITLE_KEYS environment variable and the default being .*name.*,.*title.*

[edit] How to use (individual commands)

The shell is modelled 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:

[edit] 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. You start at the reference node and can then 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 take you back to the reference node, where you started in the first place.
  • 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.

[edit] Listing 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 #Notes about filters and for information about how to specify direction see #Notes about enum options. See man ls for more info.

[edit] 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 draw a new relationship between the current node and that other node.

[edit] Setting, renaming and removing properties

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

  • set <key> <value> with optionally the -t option (for value type) sets 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]
  • rm <key> removes a property.
  • mv <key> <new-key> renames a property from one key to another.

[edit] Deleting nodes and relationships

Deleting nodes and relationships is done with the rmrel command. It focuses on deletion of relationships, but a node can also be deleted if the deleted relationship leaves the opposite node "stranded" (i.e. it no longer has any relationships drawn to it) and the -d options is supplied. See the relationship ids with the ls -rv command.

[edit] 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. List environment variables using env

[edit] 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.

[edit] Traverse

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 $i". 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 #Notes about filters. See #Notes about enum options for the traversal order option. Even relationship types/directions are supplied using the same format as filters.

[edit] インデクシング

It's possible to reach and manipulate indexes via the index command. Options to the index command are: Example: index -i persons name (will index the name for the current node or relationship in the "persons" index).

  • -g will do exact lookup in the index and display hits. You can supply -c with a command to be executed for each hit.
  • -q will ask the 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 in an 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 an 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.

[edit] Eval

Exposes the ability to pass in arbitrary JavaScript code to be executed on the shell server, directly on the graph database. Either single-line:

neo4j-sh$ eval db.getReferenceNode().getProperty( "name" );

Or multi-line, by just typing eval as the command (ending with an empty line to denote the end):

neo4j-sh$ eval
' nodes = db.getAllNodes().iterator();
' while ( nodes.hasNext() )
'    out.println( nodes.getProperty( "name" ) );
'

The available attributes are:

  • db: The GraphDatabaseService instance
  • out: The output back to you (the shell client)
  • current: The current node or relationship you stand on

[edit] Extending the shell: Adding your own apps

Of course the shell is extendable and has a generic core which has nothing to do with Neo4j... only some of the apps do.

So you say you'd like to start a Neo4j graph database, enable the remote shell and add your own apps to it so that your apps and the standard Neo4j apps co-exist side by side?Well, here's an example of how an app could look like:

public class LsRelTypes extends GraphDatabaseApp
{
    @Override
    protected String exec( AppCommandParser parser, Session session, Output out )
            throws ShellException, RemoteException
    {
        GraphDatabaseService graphDb = getServer().getDb();
        out.println( "Types:" );
        for ( RelationshipType type : graphDb.getRelationshipTypes() )
        {
            out.println( type.name() );
        }
        return null;
    }
}

You make your app discoverable via the Java Service API, so in a file e.g. src/main/resources/META-INF/services/org.neo4j.shell.App include:

org.my.domain.MyShellApp

And you could now use it in the shell by typing lsreltypes (its name is based on the class name, but can be overridden).

If you'd like it to display some nice help information when using the help (or man) app, override the getDescription method for a general description and use addOptionDefinition method to add descriptions about (and logic to) the options you can supply when using your app.

Know that the apps reside server-side so if you have a running server and start a remote client to it from another JVM adding your apps on the client side won't affect which apps are available.

Neo4j のサイト
ツールボックス