Skip to content

Replace existing filters/filtering Raphtory APIs with composite filters and APIs/ Write tests #1982 #1991

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 51 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
3a10189
restruct filters package, impl node filter graph
shivamka1 Mar 31, 2025
40b44fb
fix bench
shivamka1 Mar 31, 2025
7d4dff6
impl and/or as left and right composition instead of vec, fix tests
shivamka1 Mar 31, 2025
03efde7
replace struct based filter expr with trait based abstraction, fix al…
shivamka1 Apr 1, 2025
43acbe5
impl node field filtered graph
shivamka1 Apr 1, 2025
9d1f73a
impl edge field filtered graph
shivamka1 Apr 1, 2025
847e5ea
ref edge property filter
shivamka1 Apr 1, 2025
0bab9d6
impl and/or filtered graph
shivamka1 Apr 2, 2025
48a3a7d
Merge branch 'master' into features/new-filter-apis
shivamka1 Apr 2, 2025
67fe9a5
fix bench
shivamka1 Apr 2, 2025
5271646
ref
shivamka1 Apr 2, 2025
2432809
fix graphql for new filter abs
shivamka1 Apr 2, 2025
864027c
impl filter abs in python
shivamka1 Apr 2, 2025
1ce7ea3
impl python for new filter expr abstraction
shivamka1 Apr 2, 2025
32931f1
make filter expr work with filter apis
shivamka1 Apr 3, 2025
2cbe89f
fix infinite recursion
ljeub-pometry Apr 3, 2025
f85981d
fix/add py tests
shivamka1 Apr 4, 2025
733318c
more python tests
shivamka1 Apr 4, 2025
3827c90
fmt
shivamka1 Apr 4, 2025
f782b8c
fix tests
shivamka1 Apr 4, 2025
ce93d7b
add filter api tests for rest WIP
shivamka1 Apr 4, 2025
119546d
move search tests and ref
shivamka1 Apr 6, 2025
2d78d03
ref, fix tests
shivamka1 Apr 6, 2025
4b325f1
Merge branch 'master' into features/new-filter-apis
shivamka1 Apr 6, 2025
db2fa3c
impl filter tests for cached view graph
shivamka1 Apr 7, 2025
40df3e9
ref persistent graph
shivamka1 Apr 7, 2025
c046d2e
impl filter tests for layered graph
shivamka1 Apr 7, 2025
2eb7aa1
impl filter tests for node subgraph
shivamka1 Apr 7, 2025
1a655be
impl tests for node type filtered subgraph view
shivamka1 Apr 7, 2025
95d079c
impl filter tests for window graph
shivamka1 Apr 8, 2025
3772d4c
ref tests
shivamka1 Apr 8, 2025
3bb8be8
fix tests
shivamka1 Apr 8, 2025
9038605
fix tests
shivamka1 Apr 8, 2025
9611982
fix tests
shivamka1 Apr 8, 2025
49025dc
fix semantics
shivamka1 Apr 10, 2025
f2dc3eb
impl name, type builder in python
shivamka1 Apr 11, 2025
5511068
fix tests
shivamka1 Apr 11, 2025
ed208e7
fix tests
shivamka1 Apr 11, 2025
92c0fb8
change includes/excludes to is_in/is_not_in
shivamka1 Apr 11, 2025
07ada34
ref
shivamka1 Apr 13, 2025
29c111a
add fuzzy search filter test
shivamka1 Apr 13, 2025
30ed02f
impl contains and contains_not for filter
shivamka1 Apr 13, 2025
b5f10cf
support both tokenized and non-tokenized search queries
shivamka1 Apr 14, 2025
60a3a69
impl filter_expr for graphql fitler apis, fix all warnings, impl/fix …
shivamka1 Apr 15, 2025
84d12cd
merge from master
shivamka1 Apr 15, 2025
947268b
fixed bug where graphql property model for list was not getting trans…
shivamka1 Apr 15, 2025
6d041f8
ref, fix tests, rid duplicate tests
shivamka1 Apr 15, 2025
3401e12
Merge branch 'master' into features/new-filter-apis
shivamka1 Apr 15, 2025
d5c67b6
merge from master
shivamka1 Apr 16, 2025
67481fb
Merge branch 'master' into features/new-filter-apis
shivamka1 Apr 16, 2025
462e776
Merge branch 'master' into features/new-filter-apis
shivamka1 Apr 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
from raphtory import Graph, PersistentGraph, Prop
from raphtory import filter


def init_graph(graph):
edges = [
(6, "N1", "N2", {"p1": 2}),
(7, "N1", "N2", {"p1": 1}),
(6, "N2", "N3", {"p1": 1}),
(7, "N2", "N3", {"p1": 2}),
(8, "N3", "N4", {"p1": 1}),
(9, "N4", "N5", {"p1": 1}),
(5, "N5", "N6", {"p1": 1}),
(6, "N5", "N6", {"p1": 2}),
(5, "N6", "N7", {"p1": 1}),
(6, "N6", "N7", {"p1": 1}),
(3, "N7", "N8", {"p1": 1}),
(5, "N7", "N8", {"p1": 1}),
(3, "N8", "N9", {"p1": 1}),
(4, "N8", "N9", {"p1": 2}),
(2, "N9", "N10", {"p1": 2}),
(2, "N10", "N11", {"q1": 0}),
(2, "N10", "N11", {"p1": 3}),
(2, "N11", "N12", {"p1": 3}),
(2, "N11", "N12", {"q1": 0}),
(2, "N12", "N13", {"q1": 0}),
(3, "N12", "N13", {"p1": 3}),
(2, "N13", "N14", {"q1": 0}),
(3, "N13", "N14", {"p1": 3}),
(2, "N14", "N15", {"q1": 0}),
(2, "N15", "N1", {}),
]

for time, src, dst, props in edges:
graph.add_edge(time, src, dst, props)

constant_properties = [
("N1", "N2", {"p1": 1}),
("N4", "N5", {"p1": 2}),
("N9", "N10", {"p1": 1}),
("N10", "N11", {"p1": 1}),
("N11", "N12", {"p1": 1}),
("N12", "N13", {"p1": 1}),
("N13", "N14", {"p1": 1}),
("N14", "N15", {"p1": 1}),
("N15", "N1", {"p1": 1}),
]

for src, dst, props in constant_properties:
graph.edge(src, dst).add_constant_properties(props)

return graph


def init_graph_for_secondary_indexes(graph):
edges = [
(1, "N16", "N15", {"p1": 2}),
(1, "N16", "N15", {"p1": 1}),
(1, "N17", "N16", {"p1": 1}),
(1, "N17", "N16", {"p1": 2}),
]

for time, src, dst, props in edges:
graph.add_edge(time, src, dst, props)

return graph


def test_constant_semantics():
graph = Graph()
graph = init_graph(graph)

filter_expr = filter.Property("p1").constant() == 1
result_ids = sorted(graph.filter_edges(filter_expr).edges.id)
expected_ids = sorted([("N1","N2"), ("N10","N11"), ("N11","N12"), ("N12","N13"), ("N13","N14"), ("N14","N15"), ("N15","N1"), ("N9","N10")])
assert result_ids == expected_ids


def test_temporal_any_semantics():
graph = Graph()
graph = init_graph(graph)

filter_expr = filter.Property("p1").temporal().any() == 1

result_ids = sorted(graph.filter_edges(filter_expr).edges.id)
expected_ids = sorted([("N1","N2"), ("N2","N3"), ("N3","N4"), ("N4","N5"), ("N5","N6"), ("N6","N7"), ("N7","N8"),("N8","N9")])
assert result_ids == expected_ids


def test_temporal_any_semantics_for_secondary_indexes():
graph = Graph()
graph = init_graph(graph)
graph = init_graph_for_secondary_indexes(graph)

filter_expr = filter.Property("p1").temporal().any() == 1

result_ids = sorted(graph.filter_edges(filter_expr).edges.id)
expected_ids = sorted([("N1","N2"), ("N16","N15"), ("N17","N16"), ("N2","N3"), ("N3","N4"), ("N4","N5"), ("N5","N6"), ("N6","N7"), ("N7","N8"), ("N8","N9")])
assert result_ids == expected_ids


def test_temporal_latest_semantics():
graph = Graph()
graph = init_graph(graph)

filter_expr = filter.Property("p1").temporal().latest() == 1
result_ids = sorted(graph.filter_edges(filter_expr).edges.id)
expected_ids = sorted([("N1","N2"), ("N3","N4"), ("N4","N5"), ("N6","N7"), ("N7","N8")])
assert result_ids == expected_ids


def test_temporal_latest_semantics_for_secondary_indexes():
graph = Graph()
graph = init_graph(graph)
graph = init_graph_for_secondary_indexes(graph)

filter_expr = filter.Property("p1").temporal().latest() == 1
result_ids = sorted(graph.filter_edges(filter_expr).edges.id)
expected_ids = sorted([("N1","N2"), ("N16","N15"), ("N3","N4"), ("N4","N5"), ("N6","N7"), ("N7","N8")])
assert result_ids == expected_ids


def test_property_semantics():
graph = Graph()
graph = init_graph(graph)

filter_expr = filter.Property("p1") == 1
result_ids = sorted(graph.filter_edges(filter_expr).edges.id)
expected_ids = sorted([("N1","N2"), ("N14","N15"), ("N15","N1"), ("N3","N4"), ("N4","N5"), ("N6","N7"), ("N7","N8")])
assert result_ids == expected_ids


def test_property_semantics_for_secondary_indexes():
graph = Graph()
graph = init_graph(graph)
graph = init_graph_for_secondary_indexes(graph)

filter_expr = filter.Property("p1") == 1
result_ids = sorted(graph.filter_edges(filter_expr).edges.id)
expected_ids = sorted([("N1","N2"), ("N14","N15"), ("N15","N1"), ("N16","N15"), ("N3","N4"), ("N4","N5"), ("N6","N7"), ("N7","N8")])
assert result_ids == expected_ids


def test_property_semantics_only_constant():
# For this graph there won't be any temporal property index for property name "p1".
graph = Graph()
edges = [
(2, "N1", "N2", {"q1": 0}),
(2, "N2", "N3", {}),
]

for time, src, dst, props in edges:
graph.add_edge(time, src, dst, props)

constant_properties = [
("N1", "N2", {"p1": 1}),
("N2", "N3", {"p1": 1}),
]

for src, dst, props in constant_properties:
graph.edge(src, dst).add_constant_properties(props)

filter_expr = filter.Property("p1") == 1
result_ids = sorted(graph.filter_edges(filter_expr).edges.id)
expected_ids = sorted([("N1","N2"), ("N2","N3")])
assert result_ids == expected_ids


def test_property_semantics_only_temporal():
# For this graph there won't be any constant property index for property name "p1".
graph = Graph()

edges = [
(2, "N1", "N2", {"p1": 1}),
(2, "N2", "N3", {"p1": 1}),
(2, "N2", "N3", {"p1": 2}),
(2, "N3", "N4", {"p1": 2}),
(2, "N3", "N4", {"p1": 1}),
(2, "N4", "N5", {}),
]

for time, src, dst, props in edges:
graph.add_edge(time, src, dst, props)

constant_properties = [
("N1", "N2", {"p2": 1}),
]

for src, dst, props in constant_properties:
graph.edge(src, dst).add_constant_properties(props)

filter_expr = filter.Property("p1") == 1
result_ids = sorted(graph.filter_edges(filter_expr).edges.id)
expected_ids = sorted([("N1","N2"), ("N3","N4")])
assert result_ids == expected_ids

Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
from raphtory import Graph, PersistentGraph, Prop
from raphtory import filter


def init_graph(graph):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put all init graphs in the same place?

nodes = [
(6, "N1", {"p1": 2}),
(7, "N1", {"p1": 1}),
(6, "N2", {"p1": 1}),
(7, "N2", {"p1": 2}),
(8, "N3", {"p1": 1}),
(9, "N4", {"p1": 1}),
(5, "N5", {"p1": 1}),
(6, "N5", {"p1": 2}),
(5, "N6", {"p1": 1}),
(6, "N6", {"p1": 1}),
(3, "N7", {"p1": 1}),
(5, "N7", {"p1": 1}),
(3, "N8", {"p1": 1}),
(4, "N8", {"p1": 2}),
(2, "N9", {"p1": 2}),
(2, "N10", {"q1": 0}),
(2, "N10", {"p1": 3}),
(2, "N11", {"p1": 3}),
(2, "N11", {"q1": 0}),
(2, "N12", {"q1": 0}),
(3, "N12", {"p1": 3}),
(2, "N13", {"q1": 0}),
(3, "N13", {"p1": 3}),
(2, "N14", {"q1": 0}),
(2, "N15", {}),
]

for time, label, props in nodes:
graph.add_node(time, label, props)

constant_properties = {
"N1": {"p1": 1},
"N4": {"p1": 2},
"N9": {"p1": 1},
"N10": {"p1": 1},
"N11": {"p1": 1},
"N12": {"p1": 1},
"N13": {"p1": 1},
"N14": {"p1": 1},
"N15": {"p1": 1},
}

for label, props in constant_properties.items():
graph.node(label).add_constant_properties(props)

return graph


def init_graph_for_secondary_indexes(graph):
graph.add_node(1, "N16", {"p1": 2})
graph.add_node(1, "N16", {"p1": 1})

graph.add_node(1, "N17", {"p1": 1})
graph.add_node(1, "N17", {"p1": 2})

return graph


def test_constant_semantics():
graph = Graph()
graph = init_graph(graph)

filter_expr = filter.Property("p1").constant() == 1
result_ids = sorted(graph.filter_nodes(filter_expr).nodes.id)
expected_ids = sorted(["N1", "N10", "N11", "N12", "N13", "N14", "N15", "N9"])
assert result_ids == expected_ids


def test_temporal_any_semantics():
graph = Graph()
graph = init_graph(graph)

filter_expr = filter.Property("p1").temporal().any() == 1

result_ids = sorted(graph.filter_nodes(filter_expr).nodes.id)
expected_ids = sorted(["N1", "N2", "N3", "N4", "N5", "N6", "N7", "N8"])
assert result_ids == expected_ids


def test_temporal_any_semantics_for_secondary_indexes():
graph = Graph()
graph = init_graph(graph)
graph = init_graph_for_secondary_indexes(graph)

filter_expr = filter.Property("p1").temporal().any() == 1

result_ids = sorted(graph.filter_nodes(filter_expr).nodes.id)
expected_ids = sorted(["N1", "N16", "N17", "N2", "N3", "N4", "N5", "N6", "N7", "N8"])
assert result_ids == expected_ids


def test_temporal_latest_semantics():
graph = Graph()
graph = init_graph(graph)

filter_expr = filter.Property("p1").temporal().latest() == 1
result_ids = sorted(graph.filter_nodes(filter_expr).nodes.id)
expected_ids = sorted(["N1", "N3", "N4", "N6", "N7"])
assert result_ids == expected_ids


def test_temporal_latest_semantics_for_secondary_indexes():
graph = Graph()
graph = init_graph(graph)
graph = init_graph_for_secondary_indexes(graph)

filter_expr = filter.Property("p1").temporal().latest() == 1
result_ids = sorted(graph.filter_nodes(filter_expr).nodes.id)
expected_ids = sorted(["N1", "N16", "N3", "N4", "N6", "N7"])
assert result_ids == expected_ids


def test_property_semantics():
graph = Graph()
graph = init_graph(graph)

filter_expr = filter.Property("p1") == 1
result_ids = sorted(graph.filter_nodes(filter_expr).nodes.id)
expected_ids = sorted(["N1", "N14", "N15", "N3", "N4", "N6", "N7"])
assert result_ids == expected_ids


def test_property_semantics_for_secondary_indexes():
graph = Graph()
graph = init_graph(graph)
graph = init_graph_for_secondary_indexes(graph)

filter_expr = filter.Property("p1") == 1
result_ids = sorted(graph.filter_nodes(filter_expr).nodes.id)
expected_ids = sorted(["N1", "N14", "N15", "N16", "N3", "N4", "N6", "N7"])
assert result_ids == expected_ids


def test_property_semantics_only_constant():
# For this graph there won't be any temporal property index for property name "p1".
graph = Graph()
nodes = [
(2, "N1", {"q1": 0}),
(2, "N2", {}),
]

for time, label, props in nodes:
graph.add_node(time, label, props)

constant_properties = {
"N1": {"p1": 1},
"N2": {"p1": 1},
}

for label, props in constant_properties.items():
graph.node(label).add_constant_properties(props)

filter_expr = filter.Property("p1") == 1
result_ids = sorted(graph.filter_nodes(filter_expr).nodes.id)
expected_ids = sorted(["N1", "N2"])
assert result_ids == expected_ids


def test_property_semantics_only_temporal():
# For this graph there won't be any constant property index for property name "p1".
graph = Graph()
nodes = [
(1, "N1", {"p1": 1}),

(2, "N2", {"p1": 1}),
(3, "N2", {"p1": 2}),

(2, "N3", {"p1": 2}),
(3, "N3", {"p1": 1}),

(2, "N4", {}),
]

for time, label, props in nodes:
graph.add_node(time, label, props)

constant_properties = {
"N1": {"p2": 1},
"N2": {"p1": 1},
}

for label, props in constant_properties.items():
graph.node(label).add_constant_properties(props)

filter_expr = filter.Property("p1") == 1
result_ids = sorted(graph.filter_nodes(filter_expr).nodes.id)
expected_ids = sorted(["N1", "N3"])
assert result_ids == expected_ids

Loading
Loading