Commit 544fa8d6 authored by Tim Bleimehl's avatar Tim Bleimehl 🤸🏼
Browse files

add node filter feat

parent 6359ee8a
Pipeline #1653 passed with stage
in 1 minute and 1 second
from __future__ import annotations from __future__ import annotations
from typing import Union, List, Dict, Generic, TYPE_CHECKING from typing import Union, List, Dict, Generic, TYPE_CHECKING
from bleach import clean
if TYPE_CHECKING: if TYPE_CHECKING:
from NeoMetaTracker.capture_point import CapturePoint from NeoMetaTracker.capture_point import CapturePoint
from pathlib import Path from pathlib import Path
...@@ -26,7 +28,7 @@ class GraphSchema(py2neo.Subgraph): ...@@ -26,7 +28,7 @@ class GraphSchema(py2neo.Subgraph):
@classmethod @classmethod
def from_neo4j_schema_vis_data( def from_neo4j_schema_vis_data(
cls, cls,
neo4j_schema_vis_data: Dict, neo4j_schema_vis_data: Dict[str, List[Union[py2neo.Node, py2neo.Relationship]]],
parent_capture_point: CapturePoint, parent_capture_point: CapturePoint,
extra_props: Dict = None, extra_props: Dict = None,
) -> "GraphSchema": ) -> "GraphSchema":
...@@ -44,7 +46,8 @@ class GraphSchema(py2neo.Subgraph): ...@@ -44,7 +46,8 @@ class GraphSchema(py2neo.Subgraph):
if not extra_props: if not extra_props:
extra_props = {} extra_props = {}
extra_props = extra_props | {"__neo_meta_logger_node": True} extra_props = extra_props | {"__neo_meta_logger_node": True}
# copy all nodes to track if they are involed in a relation
nodes_without_relation = list(neo4j_schema_vis_data["nodes"])
for rel in neo4j_schema_vis_data["relationships"]: for rel in neo4j_schema_vis_data["relationships"]:
rel_nodes = [None, None] rel_nodes = [None, None]
...@@ -52,11 +55,16 @@ class GraphSchema(py2neo.Subgraph): ...@@ -52,11 +55,16 @@ class GraphSchema(py2neo.Subgraph):
if rel_nodes[0] and rel_nodes[1]: if rel_nodes[0] and rel_nodes[1]:
break break
if node.identity in [rel.start_node.identity, rel.end_node.identity]: if node.identity in [rel.start_node.identity, rel.end_node.identity]:
if node in nodes_without_relation:
nodes_without_relation.remove(node)
clean_rel_node = cls._get_or_create_unbound_schema_node( clean_rel_node = cls._get_or_create_unbound_schema_node(
node=node, node=node,
parent_capture_point=parent_capture_point, parent_capture_point=parent_capture_point,
extra_props=extra_props, extra_props=extra_props,
) )
if clean_rel_node is None:
# the node was filterd out
continue
if rel.start_node.identity == rel.end_node.identity: if rel.start_node.identity == rel.end_node.identity:
rel_nodes[0] = rel_nodes[1] = clean_rel_node rel_nodes[0] = rel_nodes[1] = clean_rel_node
elif node.identity == rel.start_node.identity: elif node.identity == rel.start_node.identity:
...@@ -80,8 +88,16 @@ class GraphSchema(py2neo.Subgraph): ...@@ -80,8 +88,16 @@ class GraphSchema(py2neo.Subgraph):
schema_graph = schema_graph | clean_rel schema_graph = schema_graph | clean_rel
# atm we ignored any nodes without any relation. # atm we ignored any nodes without any relation.
# lets make up that leeway
single_nodes_cleaned = [] single_nodes_cleaned = []
for node in neo4j_schema_vis_data["nodes"]: for node in nodes_without_relation:
clean_node = cls._get_or_create_unbound_schema_node(
node=node,
parent_capture_point=parent_capture_point,
extra_props=extra_props,
)
if clean_node is None:
continue
single_nodes_cleaned.append( single_nodes_cleaned.append(
cls._get_or_create_unbound_schema_node( cls._get_or_create_unbound_schema_node(
node=node, node=node,
...@@ -113,9 +129,7 @@ class GraphSchema(py2neo.Subgraph): ...@@ -113,9 +129,7 @@ class GraphSchema(py2neo.Subgraph):
] ]
!= parent_capture_point.labels[tuple(node.labels)[0]] != parent_capture_point.labels[tuple(node.labels)[0]]
): ):
parent_capture_point.parent_logger.all_schema_nodes[ clean_node = py2neo.Node(
tuple(node.labels)
] = clean_rel_node = py2neo.Node(
*list(node.labels), *list(node.labels),
**( **(
extra_props extra_props
...@@ -127,11 +141,17 @@ class GraphSchema(py2neo.Subgraph): ...@@ -127,11 +141,17 @@ class GraphSchema(py2neo.Subgraph):
} }
), ),
) )
clean_rel_node.__primarykey__ = "__label_name" clean_node.__primarykey__ = "__label_name"
clean_rel_node.__primarylabel__ = list(node.labels)[0] clean_node.__primarylabel__ = list(node.labels)[0]
if parent_capture_point.parent_logger.node_filter_func(clean_node):
parent_capture_point.parent_logger.all_schema_nodes[
tuple(node.labels)
] = clean_node
else:
return None
else: else:
clean_rel_node = parent_capture_point.parent_logger.all_schema_nodes[ clean_node = parent_capture_point.parent_logger.all_schema_nodes[
tuple(node.labels) tuple(node.labels)
] ]
return clean_rel_node return clean_node
...@@ -35,6 +35,22 @@ class NeoMetaTracker: ...@@ -35,6 +35,22 @@ class NeoMetaTracker:
) )
) )
def node_filter_func(self, node: py2neo.Node):
"""This function can be overiden to filter specifics nodes out of the schema tracker
example; Remove all schema-nodes with label starting with "_":
mlog = NeoMetaTracker(test_graph)
def node_filter(node: py2neo.Node):
if list(node.labels)[0].startswith("_"):
return None
return node
mlog.node_filter_func = node_filter
"""
return node
def visualize(self, visualizer_class: BaseVisualizer, to_file: Union[str, Path]): def visualize(self, visualizer_class: BaseVisualizer, to_file: Union[str, Path]):
schemas_changes = [] schemas_changes = []
for index, to_cp in enumerate(self.capture_points): for index, to_cp in enumerate(self.capture_points):
......
...@@ -26,7 +26,19 @@ graph.run("CREATE OR REPLACE DATABASE test") ...@@ -26,7 +26,19 @@ graph.run("CREATE OR REPLACE DATABASE test")
test_graph = py2neo.Graph(**(NEO4J | {"name": "test"})) test_graph = py2neo.Graph(**(NEO4J | {"name": "test"}))
# test_graph = py2neo.Graph(**(NEO4J)) # test_graph = py2neo.Graph(**(NEO4J))
mlog = NeoMetaTracker(test_graph) mlog = NeoMetaTracker(test_graph)
def node_filter(node: py2neo.Node):
if list(node.labels)[0].startswith("_"):
return None
return node
mlog.node_filter_func = node_filter
mlog.capture(name="Init") mlog.capture(name="Init")
test_graph.run("CREATE (:Alien {name: 'E.T.'})")
mlog.capture("AlienCluster")
test_graph.run("CREATE (:Human{name:'Amina Okujewa'})") test_graph.run("CREATE (:Human{name:'Amina Okujewa'})")
test_graph.run("CREATE (as:Human{name:'Aaron Swartz'})") test_graph.run("CREATE (as:Human{name:'Aaron Swartz'})")
mlog.capture(name="HumansCluster") mlog.capture(name="HumansCluster")
...@@ -56,6 +68,8 @@ test_graph.run( ...@@ -56,6 +68,8 @@ test_graph.run(
"MATCH (wH:World{name:'House'}),(wE:World{name:'Earth'}),(mp:Pig{name:'Miss Piggy'}) CREATE (mp)-[:LIVES_ON]->(wH),(mp)-[:LIVES_ON]->(wE)" "MATCH (wH:World{name:'House'}),(wE:World{name:'Earth'}),(mp:Pig{name:'Miss Piggy'}) CREATE (mp)-[:LIVES_ON]->(wH),(mp)-[:LIVES_ON]->(wE)"
) )
mlog.capture(name="RelationCluster") mlog.capture(name="RelationCluster")
test_graph.run("CREATE (:_SystemNode{name:'test'})")
mlog.capture()
print("###get_numeric_last_changes###\n", mlog.get_numeric_last_changes()) print("###get_numeric_last_changes###\n", mlog.get_numeric_last_changes())
print("###get_schemagraph_last_changes###\n", mlog.get_schemagraph_last_changes()) print("###get_schemagraph_last_changes###\n", mlog.get_schemagraph_last_changes())
print( print(
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment