The entire module has been deprecated in py2neo 1.6.2 and will be removed completely in 1.7.0.

Geoff should now be used via the load2neo extension that provides more efficient and more consistent behaviour. This facility can be accessed client-side by using the load_geoff method when the extension has been installed on the server.


The module requires server version 1.8.2 or above.

Geoff is a textual interchange format for graph data, designed with Neo4j in mind. It can be seen as a graphical equivalent of CSV and is intended to be clear and familiar with a shallow learning curve.

The geoff module represents an evolution of the format originally packaged with py2neo and the one provided by the server plugin. While this module is fully backward compatible with the older, simpler syntax, use of the new syntax is encouraged wherever possible. The server plugin will be enhanced at some point in the future.


Geoff can be used to represent a snapshot of graph data. It is purely declarative and borrows much of its syntax from Cypher. A Geoff file is represents a single subgraph and contains a number of elements separated by whitespace. These elements may be paths, index entries or comments. The example below shows all three of these element types within a single subgraph:

/* Link to Alice and Bob from within the People index */
|People {"email":""}|=>(alice)
|People {"email":""}|=>(bob)

/* Alice knows Bob */
(alice {"name":"Alice"})-[:KNOWS]->(bob {"name":"Bob"})


A Geoff path consists of one or more nodes connected by relationships. The simplest path is a single node which may or may not contain properties:

(alice {"name":"Alice"})

Any number of nodes may be chained together with relationships, for example:

(alice)-[:KNOWS]->(bob {"name":"Bob"})
(bob)-[:KNOWS]->(carol {"name":"Carol"})-[:KNOWS]->(dave {"name":"Dave"})

Path relationships do not all have to flow in the same direction:


Relationships may also have properties:

(sun)-[:PLANET {"distance":149600000,"unit":"km"}]->(earth)

Index Entries

Index entries denote entries within Neo4j node indexes bound to a single key-value pair. These elements use pipe symbols (|) and heavy arrows (=>):

|People {"email":""}|=>(alice {"name":"Alice"})
(bob {"name":"Bob"})<=|People {"email":""}|


Relationship index entries are no longer supported within Geoff.


Comment elements may be included between other elements and have the same syntax as C/Java multiline comments, between /* and */.


class py2neo.geoff.Subgraph(source)[source]
insert_into(*args, **kwargs)[source]

Insert subgraph into graph database using Cypher CREATE.

classmethod load(file)[source]

Load Geoff data from a file into a Subgraph.

classmethod load_xml(file, prefixes=None)[source]

Load and convert data within an XML file into a Subgraph.

merge_into(*args, **kwargs)[source]

Merge subgraph into graph database using Cypher CREATE UNIQUE.


Save subgraph to a file in Geoff format.


Return the Geoff source for this Subgraph.

class py2neo.geoff.ConstraintViolation[source]

Raised on an attempt to merge a unique path onto a non-unique path.

Module Functions

py2neo.geoff.insert(graph_db, file)[source]

Insert Geoff data into a graph database.

py2neo.geoff.merge(graph_db, file)[source]

Merge Geoff data into a graph database.

py2neo.geoff.insert_xml(graph_db, file)[source]

Insert XML data into a graph database.

py2neo.geoff.merge_xml(graph_db, file)[source]

Merge XML data into a graph database.

Full Geoff Syntax Specification (version 2)

subgraph       := [element (_ element)*]
element        := path | index_entry | comment

path           := node (forward_path | reverse_path)*
forward_path   := "-" relationship "->" node
reverse_path   := "<-" relationship "-" node

index_entry    := forward_entry | reverse_entry
forward_entry  := "|" ~ index_name _ property_pair ~ "|" "=>" node
reverse_entry  := node "<=" "|" ~ index_name _ property_pair ~ "|"
index_name     := name | JSON_STRING

comment        := "/*" <<any text excluding sequence "*/">> "*/"

node           := named_node | anonymous_node
named_node     := "(" ~ node_name [_ property_map] ~ ")"
anonymous_node := "(" ~ [property_map ~] ")"
relationship   := "[" ~ ":" type [_ property_map] ~ "]"
property_pair  := "{" ~ key_value ~ "}"
property_map   := "{" ~ [key_value (~ "," ~ key_value)* ~] "}"
node_name      := name | JSON_STRING
name           := (ALPHA | DIGIT | "_")+
type           := name | JSON_STRING
key_value      := key ~ ":" ~ value
key            := name | JSON_STRING
value          := array | JSON_STRING | JSON_NUMBER | JSON_BOOLEAN | JSON_NULL

array          := empty_array | string_array | numeric_array | boolean_array
empty_array    := "[" ~ "]"
string_array   := "[" ~ JSON_STRING (~ "," ~ JSON_STRING)* ~ "]"
numeric_array  := "[" ~ JSON_NUMBER (~ "," ~ JSON_NUMBER)* ~ "]"
boolean_array  := "[" ~ JSON_BOOLEAN (~ "," ~ JSON_BOOLEAN)* ~ "]"

* Mandatory whitespace is represented by "_" and optional whitespace by "~"

Table Of Contents

Previous topic

Object-Graph Mapping (OGM)

Next topic

Date Modelling

This Page