class Subgraph
A class representing a graph subgraph containing nodes and relationships, with support for set operations and graph binding/unbinding.
/tf/active/vicechatdev/neo4j_driver/neo4j_objects.py
393 - 459
moderate
Purpose
The Subgraph class models a subset of a graph structure, managing collections of nodes and relationships. It provides graph algebra operations (union, intersection, difference, symmetric difference) and supports binding/unbinding from a parent graph. This is typically used in graph database operations to work with portions of larger graphs, allowing manipulation and combination of graph fragments.
Source Code
class Subgraph():
def __init__(self, nodes=None, relationships=None, graph=None):
self._graph = graph
self._nodes = frozenset(nodes or [])
self._relationships = frozenset(relationships or [])
self._nodes |= frozenset(chain.from_iterable(r.nodes for r in self._relationships))
@property
def nodes(self):
return set(self._nodes)
@property
def relationships(self):
return set(self._relationships)
@property
def graph(self):
return self._graph
@graph.setter
def graph(self, graph):
self._graph = graph
def unbind(self):
"""Returns an unbound copy of itself"""
out = Subgraph()
created_nodes = []
for r in self.relationships:
if r.start_node['UID'] in created_nodes:
start = [i for i in out.nodes if i['UID'] == r.start_node['UID']][0]
else:
start = r.start_node.unbind()
created_nodes.append(start['UID'])
if r.end_node['UID'] in created_nodes:
end = [i for i in out.nodes if i['UID'] == r.end_node['UID']][0]
else:
end = r.end_node.unbind()
created_nodes.append(end['UID'])
out = out | Relationship(start, _Relationship(*r.labels, **r.relationship), end)
return out
def __str__(self):
return "Nodes(%s), \nRelationships(%s)" % (self.nodes,
self.relationships)
def __repr__(self):
return "Nodes(%s), \nRelationships(%s)" % (self.nodes,
self.relationships)
def __bool__(self):
return len(self.nodes) > 0
def __or__(self, other):
return Subgraph(set(self.nodes) | set(other.nodes), set(self.relationships) | set(other.relationships))
def __and__(self, other):
return Subgraph(set(self.nodes) & set(other.nodes), set(self.relationships) & set(other.relationships))
def __sub__(self, other):
r = set(self.relationships) - set(other.relationships)
n = (set(self.nodes) - set(other.nodes)) | set().union(*(set(rel.nodes) for rel in r))
return Subgraph(n, r)
def __xor__(self, other):
r = set(self.relationships) ^ set(other.relationships)
n = (set(self.nodes) ^ set(other.nodes)) | set().union(*(set(rel.nodes) for rel in r))
return Subgraph(n, r)
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
bases |
- | - |
Parameter Details
nodes: Optional iterable of node objects to include in the subgraph. Can be None or empty. These nodes will be stored as a frozenset internally.
relationships: Optional iterable of relationship objects connecting nodes. Can be None or empty. The subgraph will automatically include all nodes referenced by these relationships, even if not explicitly provided in the nodes parameter.
graph: Optional reference to a parent graph object that this subgraph belongs to. Used for maintaining context and binding state.
Return Value
Instantiation returns a Subgraph object containing the specified nodes and relationships. The nodes property returns a mutable set of nodes, relationships property returns a mutable set of relationships, and graph property returns the parent graph reference. The unbind() method returns a new unbound Subgraph copy. Set operations (__or__, __and__, __sub__, __xor__) return new Subgraph instances.
Class Interface
Methods
__init__(nodes=None, relationships=None, graph=None)
Purpose: Initialize a Subgraph with optional nodes, relationships, and parent graph reference
Parameters:
nodes: Optional iterable of node objectsrelationships: Optional iterable of relationship objectsgraph: Optional parent graph reference
Returns: None (constructor)
@property nodes(self) -> set
property
Purpose: Get a mutable set of all nodes in the subgraph
Returns: Set containing all node objects in the subgraph
@property relationships(self) -> set
property
Purpose: Get a mutable set of all relationships in the subgraph
Returns: Set containing all relationship objects in the subgraph
@property graph(self)
property
Purpose: Get the parent graph reference
Returns: The parent graph object or None if unbound
@graph.setter graph(self, graph)
property
Purpose: Set the parent graph reference
Parameters:
graph: The parent graph object to bind to
Returns: None
unbind(self) -> Subgraph
Purpose: Create an unbound copy of the subgraph with unbound nodes and relationships
Returns: A new Subgraph instance with unbound copies of all nodes and relationships
__str__(self) -> str
Purpose: Return string representation of the subgraph
Returns: String showing nodes and relationships
__repr__(self) -> str
Purpose: Return detailed string representation of the subgraph
Returns: String showing nodes and relationships
__bool__(self) -> bool
Purpose: Check if subgraph contains any nodes
Returns: True if subgraph has nodes, False otherwise
__or__(self, other: Subgraph) -> Subgraph
Purpose: Perform union operation with another subgraph
Parameters:
other: Another Subgraph instance to union with
Returns: New Subgraph containing union of nodes and relationships
__and__(self, other: Subgraph) -> Subgraph
Purpose: Perform intersection operation with another subgraph
Parameters:
other: Another Subgraph instance to intersect with
Returns: New Subgraph containing intersection of nodes and relationships
__sub__(self, other: Subgraph) -> Subgraph
Purpose: Perform difference operation with another subgraph
Parameters:
other: Another Subgraph instance to subtract
Returns: New Subgraph containing elements in self but not in other, preserving nodes connected by remaining relationships
__xor__(self, other: Subgraph) -> Subgraph
Purpose: Perform symmetric difference operation with another subgraph
Parameters:
other: Another Subgraph instance for symmetric difference
Returns: New Subgraph containing elements in either subgraph but not both, preserving nodes connected by remaining relationships
Attributes
| Name | Type | Description | Scope |
|---|---|---|---|
_graph |
object or None | Private attribute storing reference to the parent graph object | instance |
_nodes |
frozenset | Private immutable set storing all node objects in the subgraph | instance |
_relationships |
frozenset | Private immutable set storing all relationship objects in the subgraph | instance |
Dependencies
uuiditertools
Required Imports
from uuid import uuid4
from itertools import chain
Usage Example
# Assuming Node and Relationship classes are available
from itertools import chain
# Create nodes
node1 = Node('Person', name='Alice', UID='uid1')
node2 = Node('Person', name='Bob', UID='uid2')
# Create a relationship
rel = Relationship(node1, 'KNOWS', node2)
# Create subgraph with nodes and relationships
subgraph1 = Subgraph(nodes=[node1, node2], relationships=[rel])
# Create another subgraph
node3 = Node('Person', name='Charlie', UID='uid3')
subgraph2 = Subgraph(nodes=[node3])
# Combine subgraphs using union
combined = subgraph1 | subgraph2
# Get intersection
common = subgraph1 & subgraph2
# Access nodes and relationships
all_nodes = combined.nodes
all_rels = combined.relationships
# Unbind from graph
unbound_copy = subgraph1.unbind()
# Check if subgraph has nodes
if subgraph1:
print('Subgraph has nodes')
Best Practices
- Nodes and relationships are stored as frozensets internally for immutability, but exposed as mutable sets through properties
- When creating a Subgraph with relationships, you don't need to explicitly provide the connected nodes - they are automatically extracted
- The unbind() method creates a deep copy with unbound nodes and relationships, useful for detaching from a parent graph
- Set operations (|, &, -, ^) create new Subgraph instances rather than modifying existing ones
- The graph property can be set after instantiation to bind the subgraph to a parent graph
- Boolean evaluation returns True if the subgraph contains any nodes, False otherwise
- Nodes must have a 'UID' attribute for the unbind() method to work correctly
- The unbind() method assumes relationships have start_node, end_node, labels, and relationship attributes
Similar Components
AI-powered semantic similarity - components with related functionality:
-
class Graph 59.5% similar
-
class Relationship 58.0% similar
-
class _Relationship 56.1% similar
-
class Node 53.0% similar
-
class Neo4jManager 44.7% similar