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 untilcreated
ormerged
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 theSubgraph
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()
andremove_label()
for that instead.
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.
- 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 theRelationship
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
andend_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"})
- relationships¶
The sequence of
Relationship
objects 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
andRelationship
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 forNode
,Relationship
andPath
.By definition, a subgraph must contain at least one node; null subgraphs should be represented by
None
. To test for emptiness the built-inbool()
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.