py2neo.data – Graph data types

Note

For convenience, the members of py2neo.data can also be imported directly from py2neo.

Py2neo provides a rich set of data types for working with graph data. These graph data types are completely compatible with Neo4j but can also be used locally, unbound to a remote database.

All graph data values in py2neo can be combined into arbitrary Subgraph objects, which can themselves be used as arguments for many database operations, such as Graph.create. This provides a powerful way to send multiple entities to the database in a single round trip, thereby reducing the network overhead:

>>> from py2neo import *
>>> a = Node("Person", name="Alice")
>>> b = Node("Person", name="Bob")
>>> c = Node("Person", name="Carol")
>>> KNOWS = Relationship.type("KNOWS")
>>> ab = KNOWS(a, b)
>>> ba = KNOWS(b, a)
>>> ac = KNOWS(a, c)
>>> ca = KNOWS(c, a)
>>> bc = KNOWS(b, c)
>>> cb = KNOWS(c, b)
>>> friends = ab | ba | ac | ca | bc | cb
>>> g = Graph()
>>> g.create(friends)
>>> a.graph, a.identity
(Graph('bolt://neo4j@localhost:7687'), 0)

The two essential building blocks of the labelled property graph model used by Neo4j are the Node and the Relationship. The node is the primary unit of data storage within a graph. It can contain a set of properties (name-value pairs) and can optionally be adorned with one or more textual labels. A relationship is a typed, directed connection between a pair of nodes (or alternatively a loop on a single node). Like nodes, relationships may also contain a properties.

Node objects

class py2neo.data.Node(*labels, **properties)[source]

A node is a fundamental unit of data storage within a property graph that may optionally be connected, via relationships, to other nodes.

Node objects can either be created implicitly, by returning nodes in a Cypher query such as CREATE (a) RETURN a, or can be created explicitly through the constructor. In the former case, the local Node object is bound to the remote node in the database; in the latter case, the Node object remains unbound until created or merged into a Neo4j database.

It possible to combine nodes (along with relationships and other graph data objects) into Subgraph objects using set operations. For more details, look at the documentation for the Subgraph class.

All positional arguments passed to the constructor are interpreted as labels and all keyword arguments as properties:

>>> from py2neo import Node
>>> a = Node("Person", name="Alice")

Identity and equality

The properties and methods described in the section below relate to now node equality works, as well as how nodes can be uniquely identified. Note that bound nodes exhibit slightly different behaviour to unbound nodes, with respect to identity.

node == other

Return True if node and other are equal. Node equality is based solely on the ID of the remote node it represents; neither properties nor labels factor into equality. This means that if bound, a node object can only be considered equal to another node object that is bound to the same remote node. If a node is unbound, thereby having no corresponding node ID, it can only ever be equal to itself.

node != other

Return True if the nodes are unequal.

hash(node)

Return a hash of node based on its object ID, if unbound, or the ID of the remote node it represents, if bound.

graph

The remote graph to which this node is bound, if any.

identity

The ID of the remote node to which this node is bound, if any.

Labels

The property and methods below provide a way to view and manipulate the labels attached to a Node. Labels are a unique, unordered set of tags that can be used to classify and identify certain nodes.

>>> a = Node("Person", name="Alice")
>>> set(a.labels)
{'Person'}
>>> a.add_label("Employee")
>>> set(a.labels)
{'Employee', 'Person'}
labels

The full set of labels associated with with this node.

This set is immutable and cannot be used to add or remove labels. Use methods such as add_label() and remove_label() for that instead.

has_label(label)[source]

Return True if this node has the label label, False otherwise.

add_label(label)[source]

Add the label label to this node.

remove_label(label)[source]

Remove the label label from this node, if it exists.

clear_labels()[source]

Remove all labels from this node.

update_labels(labels)[source]

Add multiple labels to this node from the iterable labels.

Properties

Node properties can be queried and managed using the attributes below. Note that changes occur only on the local side of a bound node, and therefore the node must be pushed in order to propagate these changes to the remote node.

node[name]

Return the value of the property called name, or None if the name is missing.

node[name] = value

Set the value of the property called name to value, or remove the property if value is None.

del node[name]

Remove the property called name from this node, raising a KeyError if such a property does not exist.

len(node)

Return the number of properties on this node.

dict(node)

Return a dictionary of all the properties in this node.

clear()

Remove all properties from this node.

get(name, default=None)

Return the value of the property called name, or default if the name is missing.

items()

Return a list of all properties as 2-tuples of name-value pairs.

keys()[source]

Return a list of all property names.

setdefault(name, default=None)

If this node has a property called name, return its value. If not, add a new property with a value of default and return default.

update(properties, **kwproperties)

Update the properties on this node with a dictionary or name-value list of properties, plus additional kwproperties.

values()

Return a list of all property values.

Relationship objects

class py2neo.data.Relationship(start_node, type, end_node, **properties)[source]
class py2neo.data.Relationship(start_node, end_node, **properties)
class py2neo.data.Relationship(node, type, **properties)
class py2neo.data.Relationship(node, **properties)

Construct a relationship between a pair of nodes (or between a node and itself) of type type. If the type is not specified, it will default to TO. This default can be overridden by extending the Relationship class:

>>> c = Node("Person", name="Carol")
>>> class WorksWith(Relationship): pass
>>> ac = WorksWith(a, c)
>>> type(ac)
'WORKS_WITH'

Identity and equality

The properties and methods described in the section below relate to now relationship equality works, as well as how relationships can be uniquely identified. Note that bound relationships exhibit slightly different behaviour to unbound relationships, with respect to identity.

relationship == other

Return True if relationship and other are equal. Relationship equality is based on equality of the start node, the end node and the relationship type (node equality is described above). This means that any two relationships of the same type between the same nodes are always considered equal. Note that this behaviour differs slightly from Neo4j itself which permits multiple relationships of the same type between the same nodes.

relationship != other

Return True if the relationships are unequal.

hash(relationship)

Return a hash of relationship based on its start node, end node and type.

graph

The remote graph to which this relationship is bound, if any.

identity

The ID of the remote relationship to which this relationship is bound, if any.

Type and geometry

These attributes relate to the type and endpoints of relationships. Every node in Neo4j is directed, and this is reflected in the API here: Relationship objects have a designated start and end node, which can be accessed through the start_node and end_node attributes respectively.

static type(name)[source]

Return the Relationship subclass corresponding to a given name.

Parameters:

name – relationship type name

Returns:

type object

Example:

>>> KNOWS = Relationship.type("KNOWS")
>>> KNOWS(a, b)
KNOWS(Node('Person', name='Alice'), Node('Person', name='Bob')
type(relationship)

Return the Relationship subclass for relationship.

type(relationship).__name__

Return the name of the Relationship subclass for relationship as a string.

nodes

A 2-tuple of start node and end node.

start_node

The start node for this relationship.

end_node

The end node for this relationship.

Properties

Relationship properties can be queried and managed using the attributes below. Note that changes occur only on the local side of a bound relationship, and therefore the relationship must be pushed in order to propagate these changes to the remote relationship.

relationship[name]

Return the value of the property called name, or None if the name is missing.

relationship[name] = value

Set the value of the property called name to value, or remove the property if value is None.

del relationship[name]

Remove the property called name from this relationship, raising a KeyError if such a property does not exist.

len(node)

Return the number of properties on this relationship.

dict(node)

Return a dictionary of all the properties in this relationship.

clear()

Remove all properties from this relationship.

get(name, default=None)

Return the value of the property called name, or default if the name is missing.

items()

Return a list of all properties as 2-tuples of name-value pairs.

keys()

Return a list of all property names.

setdefault(name, default=None)

If this relationship has a property called name, return its value. If not, add a new property with a value of default and return default.

update(properties, **kwproperties)

Update the properties on this relationship with a dictionary or name-value list of properties, plus additional kwproperties.

values()

Return a list of all property values.

Path objects

class py2neo.data.Path(*entities)[source]

A path represents a walk through a graph, starting on a node and visiting alternating relationships and nodes thereafter. Paths have a “overlaid” direction separate to that of the relationships they contain, and the nodes and relationships themselves may each be visited multiple times, in any order, within the same path.

Paths can be returned from Cypher queries or can be constructed locally via the constructor or by using the addition operator.

The entities provided to the constructor are walked in order to build up the new path. This is only possible if the end node of each entity is the same as either the start node or the end node of the next entity; in the latter case, the second entity will be walked in reverse. Nodes that overlap from one argument onto another are not duplicated.

>>> from py2neo import Node, Path
>>> alice, bob, carol = Node(name="Alice"), Node(name="Bob"), Node(name="Carol")
>>> abc = Path(alice, "KNOWS", bob, Relationship(carol, "KNOWS", bob), carol)
>>> abc
<Path order=3 size=2>
>>> abc.nodes
(<Node labels=set() properties={'name': 'Alice'}>,
 <Node labels=set() properties={'name': 'Bob'}>,
 <Node labels=set() properties={'name': 'Carol'}>)
>>> abc.relationships
(<Relationship type='KNOWS' properties={}>,
 <Relationship type='KNOWS' properties={}>)
>>> dave, eve = Node(name="Dave"), Node(name="Eve")
>>> de = Path(dave, "KNOWS", eve)
>>> de
<Path order=2 size=1>
>>> abcde = Path(abc, "KNOWS", de)
>>> abcde
<Path order=5 size=4>
>>> for relationship in abcde.relationships:
...     print(relationship)
({name:"Alice"})-[:KNOWS]->({name:"Bob"})
({name:"Carol"})-[:KNOWS]->({name:"Bob"})
({name:"Carol"})-[:KNOWS]->({name:"Dave"})
({name:"Dave"})-[:KNOWS]->({name:"Eve"})
graph

The Graph to which this path is bound, if any.

nodes

The sequence of Node objects encountered while walking this path.

relationships

The sequence of Relationship objects encountered while walking this path.

start_node

The first Node object encountered while walking this path.

end_node

The last Node object encountered while walking this path.

types()

Return the set of all relationship types present on this path.

static walk(*walkables)[source]

Traverse over the arguments supplied, in order, yielding alternating Node and Relationship objects. Any node or relationship may be traversed one or more times in any direction.

Parameters:

walkables – sequence of walkable objects

Subgraph objects

class py2neo.data.Subgraph(nodes, relationships)[source]

A Subgraph is an arbitrary collection of nodes and relationships. It is also the base class for Node, Relationship and Path.

By definition, a subgraph must contain at least one node; null subgraphs should be represented by None. To test for emptiness the built-in bool() function can be used.

The simplest way to construct a subgraph is by combining nodes and relationships using standard set operations. For example:

>>> s = ab | ac
>>> s
{(alice:Person {name:"Alice"}),
 (bob:Person {name:"Bob"}),
 (carol:Person {name:"Carol"}),
 (Alice)-[:KNOWS]->(Bob),
 (Alice)-[:WORKS_WITH]->(Carol)}
>>> s.nodes()
frozenset({(alice:Person {name:"Alice"}),
           (bob:Person {name:"Bob"}),
           (carol:Person {name:"Carol"})})
>>> s.relationships()
frozenset({(Alice)-[:KNOWS]->(Bob),
           (Alice)-[:WORKS_WITH]->(Carol)})
subgraph | other | ...

Union. Return a new subgraph containing all nodes and relationships from subgraph as well as all those from other. Any entities common to both will only be included once.

subgraph & other & ...

Intersection. Return a new subgraph containing all nodes and relationships common to both subgraph and other.

subgraph - other - ...

Difference. Return a new subgraph containing all nodes and relationships that exist in subgraph but do not exist in other, as well as all nodes that are connected by the relationships in subgraph regardless of whether or not they exist in other.

subgraph ^ other ^ ...

Symmetric difference. Return a new subgraph containing all nodes and relationships that exist in subgraph or other, but not in both, as well as all nodes that are connected by those relationships regardless of whether or not they are common to subgraph and other.

keys()[source]

Return the set of all property keys used by the nodes and relationships in this subgraph.

labels()[source]

Return the set of all node labels in this subgraph.

Changed in version 2020.0: this is now a method rather than a property, as in previous versions.

nodes

The set of all nodes in this subgraph.

relationships

The set of all relationships in this subgraph.

types()[source]

Return the set of all relationship types in this subgraph.