Skip to content
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

impl node type filter for nodes, pathfromgraph and pathfromnode #1606

Merged
merged 33 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c270a31
fix node type filter
shivamka1 May 14, 2024
8bbe804
Merge branch 'master' into fix/node_type
shivamka1 May 14, 2024
36e76cd
rid type_filter
shivamka1 May 16, 2024
755e497
rid nodetypefilter python
shivamka1 May 17, 2024
c59d823
impl python type filter
shivamka1 May 17, 2024
8d11f27
Merge branch 'master' into fix/node_type
shivamka1 May 17, 2024
1bba94b
fmt
shivamka1 May 17, 2024
12c26f9
Merge branch 'fix/node_type' of github.com:Raphtory/Raphtory into fix…
shivamka1 May 17, 2024
c71ea06
fix graphql type filter
shivamka1 May 17, 2024
278eaef
fmt
shivamka1 May 17, 2024
8dd8d12
more tests
shivamka1 May 17, 2024
c0ecf46
impl node filter
shivamka1 May 20, 2024
6481928
add nodes type filter
shivamka1 May 20, 2024
280148f
fixed compilation errors and added node types filter after hops
fabianmurariu May 20, 2024
0996fb2
filtering by types
fabianmurariu May 20, 2024
3738bf2
impl type filter for pathfromnode and pathfromgraph
shivamka1 May 20, 2024
7ea2b95
fix len and is empty for pathfromgraph, more tests
shivamka1 May 21, 2024
41f00f1
more pathfromnode tests
shivamka1 May 21, 2024
23ab3b9
add sanity tests for window, layer and subgraph graphs
shivamka1 May 21, 2024
5e28b2e
ref, tests, fix multi hops, map node_types from Arc<[str]> to Arc<[bo…
shivamka1 May 22, 2024
1a0b8e2
fmt, more tests
shivamka1 May 22, 2024
03eca64
ref
shivamka1 May 22, 2024
8323c44
add pytest
shivamka1 May 22, 2024
c9c39a4
impl pytests
shivamka1 May 22, 2024
610944a
fix graphql and add basic tests
shivamka1 May 22, 2024
1a7ae0d
Merge remote-tracking branch 'origin/master' into fix/node_type2
miratepuffin May 28, 2024
b5b4303
Part way through merge
miratepuffin May 28, 2024
218af54
finished merge
miratepuffin May 28, 2024
56002ef
fixed internal issues
miratepuffin May 28, 2024
a78cf6a
one last fixt
miratepuffin May 28, 2024
cac690c
fmt
miratepuffin May 28, 2024
9afa2a9
Merge branch 'master' into fix/node_type2
miratepuffin May 28, 2024
60a3716
make node_type_id return 0 for arrow graph for now to pass the test. …
shivamka1 May 29, 2024
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
83 changes: 80 additions & 3 deletions python/tests/test_graphdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -2046,15 +2046,92 @@ def test_one_hop_filter_reset():
assert len(out_out_2) == 0


def test_node_types():
def test_type_filter():
g = Graph()
g.add_node(1, 1, node_type="wallet")
g.add_node(1, 2, node_type="timer")
g.add_node(1, 3, node_type="timer")
g.add_node(1, 4, node_type="wallet")

assert g.nodes.type_filter(["wallet"]).node_type.collect() == ["1", "4"]
assert g.subgraph_node_types(["timer"]).nodes.name.collect() == ["2", "3"]
assert [node.name for node in g.nodes.type_filter(["wallet"])] == ['1', '4']
assert g.subgraph_node_types(["timer"]).nodes.name.collect() == ['2', '3']

g = PersistentGraph()
g.add_node(1, 1, node_type="wallet")
g.add_node(2, 2, node_type="timer")
g.add_node(3, 3, node_type="timer")
g.add_node(4, 4, node_type="wallet")

assert [node.name for node in g.nodes.type_filter(["wallet"])] == ['1', '4']
assert g.subgraph_node_types(["timer"]).nodes.name.collect() == ['2', '3']

subgraph = g.subgraph([1, 2, 3])
assert [node.name for node in subgraph.nodes.type_filter(["wallet"])] == ['1']
assert subgraph.subgraph_node_types(["timer"]).nodes.name.collect() == ['2', '3']

w = g.window(1, 3)
assert [node.name for node in w.nodes.type_filter(["wallet"])] == ['1']
assert w.subgraph_node_types(["timer"]).nodes.name.collect() == ['2', '3']

g = Graph()
g.add_node(1, 1, node_type="wallet")
g.add_node(2, 2, node_type="timer")
g.add_node(3, 3, node_type="timer")
g.add_node(4, 4, node_type="counter")
g.add_edge(1, 1, 2, layer="layer1")
g.add_edge(2, 2, 3, layer="layer1")
g.add_edge(3, 2, 4, layer="layer2")
layer = g.layers(["layer1"])
assert [node.name for node in layer.nodes.type_filter(["wallet"])] == ['1']
assert layer.subgraph_node_types(["timer"]).nodes.name.collect() == ['2', '3']

g = Graph()
g.add_node(1, 1, node_type="a")
g.add_node(1, 2, node_type="b")
g.add_node(1, 3, node_type="b")
g.add_node(1, 4, node_type="a")
g.add_node(1, 5, node_type="c")
g.add_node(1, 6, node_type="e")
g.add_edge(2, 1, 2, layer="a")
g.add_edge(2, 3, 2, layer="a")
g.add_edge(2, 2, 4, layer="a")
g.add_edge(2, 4, 5, layer="a")
g.add_edge(2, 4, 5, layer="a")
g.add_edge(2, 5, 6, layer="a")
g.add_edge(2, 3, 6, layer="a")

assert g.nodes.type_filter(["a"]).name.collect() == ['1', '4']
assert g.nodes.type_filter(["a", "c"]).name.collect() == ['1', '4', '5']
assert g.nodes.type_filter(["a"]).neighbours.name.collect() == [['2'], ['2', '5']]

assert g.nodes.degree().collect() == [1, 3, 2, 2, 2, 2]
assert g.nodes.type_filter(['a']).degree().collect() == [1, 2]
assert g.nodes.type_filter(['d']).degree().collect() == []
assert g.nodes.type_filter([]).name.collect() == []

assert len(g.nodes) == 6
assert len(g.nodes.type_filter(['b'])) == 2
assert len(g.nodes.type_filter(['d'])) == 0

assert g.nodes.type_filter(['d']).neighbours.name.collect() == []
assert g.nodes.type_filter(['a']).neighbours.name.collect() == [['2'], ['2', '5']]
assert g.nodes.type_filter(['a', 'c']).neighbours.name.collect() == [['2'], ['2', '5'], ['4', '6']]

assert g.nodes.type_filter(['a']).neighbours.type_filter(['c']).name.collect() == [[], ['5']]
assert g.nodes.type_filter(['a']).neighbours.type_filter([]).name.collect() == [[], []]
assert g.nodes.type_filter(['a']).neighbours.type_filter(['b', 'c']).name.collect() == [['2'], ['2', '5']]
assert g.nodes.type_filter(['a']).neighbours.type_filter(['d']).name.collect() == [[], []]
assert g.nodes.type_filter(['a']).neighbours.neighbours.name.collect() == [['1', '3', '4'], ['1', '3', '4', '4', '6']]
assert g.nodes.type_filter(['a']).neighbours.type_filter(['c']).neighbours.name.collect() == [[], ['4', '6']]
assert g.nodes.type_filter(['a']).neighbours.type_filter(['d']).neighbours.name.collect() == [[], []]

assert g.node('2').neighbours.type_filter(['b']).name.collect() == ['3']
assert g.node('2').neighbours.type_filter(['d']).name.collect() == []
assert g.node('2').neighbours.type_filter([]).name.collect() == []
assert g.node('2').neighbours.type_filter(['c', 'a']).name.collect() == ['1', '4']
assert g.node('2').neighbours.type_filter(['c']).neighbours.name.collect() == []
assert g.node('2').neighbours.neighbours.name.collect() == ['2', '2', '6', '2', '5']



def test_time_exploded_edges():
Expand Down
116 changes: 116 additions & 0 deletions raphtory-graphql/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -969,4 +969,120 @@ mod graphql_test {
let graph_roundtrip = url_decode_graph(graph_encoded).unwrap().into_dynamic();
assert_eq!(g, graph_roundtrip);
}

#[tokio::test]
async fn test_type_filter() {
let graph = Graph::new();
graph.add_constant_properties([("name", "graph")]).unwrap();
graph.add_node(1, 1, NO_PROPS, Some("a")).unwrap();
graph.add_node(1, 2, NO_PROPS, Some("b")).unwrap();
graph.add_node(1, 3, NO_PROPS, Some("b")).unwrap();
graph.add_node(1, 4, NO_PROPS, Some("a")).unwrap();
graph.add_node(1, 5, NO_PROPS, Some("c")).unwrap();
graph.add_node(1, 6, NO_PROPS, Some("e")).unwrap();
graph.add_edge(2, 1, 2, NO_PROPS, Some("a")).unwrap();
graph.add_edge(2, 3, 2, NO_PROPS, Some("a")).unwrap();
graph.add_edge(2, 2, 4, NO_PROPS, Some("a")).unwrap();
graph.add_edge(2, 4, 5, NO_PROPS, Some("a")).unwrap();
graph.add_edge(2, 4, 5, NO_PROPS, Some("a")).unwrap();
graph.add_edge(2, 5, 6, NO_PROPS, Some("a")).unwrap();
graph.add_edge(2, 3, 6, NO_PROPS, Some("a")).unwrap();

let graphs = HashMap::from([("graph".to_string(), graph)]);
let data = Data::from_map(graphs);
let schema = App::create_schema().data(data).finish().unwrap();

let req = r#"
{
graph(name: "graph") {
nodes {
typeFilter(nodeTypes: ["a"]) {
list {
name
}
}
}
}
}
"#;

let req = Request::new(req);
let res = schema.execute(req).await;
let data = res.data.into_json().unwrap();
assert_eq!(
data,
json!({
"graph": {
"nodes": {
"typeFilter": {
"list": [
{
"name": "1"
},
{
"name": "4"
}
]
}
}
}
}),
);

let req = r#"
{
graph(name: "graph") {
nodes {
typeFilter(nodeTypes: ["a"]) {
list{
neighbours {
list {
name
}
}
}
}
}
}
}
"#;

let req = Request::new(req);
let res = schema.execute(req).await;
let data = res.data.into_json().unwrap();
assert_eq!(
data,
json!({
"graph": {
"nodes": {
"typeFilter": {
"list": [
{
"neighbours": {
"list": [
{
"name": "2"
}
]
}
},
{
"neighbours": {
"list": [
{
"name": "2"
},
{
"name": "5"
}
]
}
}
]
}
}
}
}),
);
}
}
2 changes: 1 addition & 1 deletion raphtory-graphql/src/model/graph/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl GqlNodes {
}

async fn type_filter(&self, node_types: Vec<String>) -> Self {
self.update(self.nn.type_filter(node_types))
self.update(self.nn.type_filter(&node_types))
}

////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion raphtory-graphql/src/model/graph/path_from_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl GqlPathFromNode {
}

async fn type_filter(&self, node_types: Vec<String>) -> Self {
self.update(self.nn.type_filter(node_types))
self.update(self.nn.type_filter(&node_types))
}

////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion raphtory-graphql/src/model/graph/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use raphtory::{
},
};
use serde_json::Number;
use std::collections::{HashMap, HashSet};
use std::collections::HashMap;

#[derive(Clone, Debug, Scalar)]
pub struct GqlPropValue(pub Prop);
Expand Down
11 changes: 10 additions & 1 deletion raphtory/src/arrow/graph_impl/core_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ use crate::{
},
storage_ops::GraphStorage,
},
view::{internal::CoreGraphOps, BoxedIter},
view::{
internal::{CoreGraphOps, DelegateCoreOps},
BoxedIter,
},
},
};
use itertools::Itertools;
use polars_arrow::datatypes::ArrowDataType;
use raphtory_arrow::{properties::Properties, GidRef, GID};
use rayon::prelude::*;

impl CoreGraphOps for ArrowGraph {
fn unfiltered_num_nodes(&self) -> usize {
self.inner.num_nodes()
Expand Down Expand Up @@ -222,6 +226,11 @@ impl CoreGraphOps for ArrowGraph {
.map(|layer| layer.num_edges())
.sum()
}

fn node_type_id(&self, v: VID) -> usize {
// self.graph().node_type_id(v) TODO: Impl node types for arrow graphs
0
}
}

pub fn const_props<Index>(props: &Properties<Index>, index: Index, id: usize) -> Option<Prop>
Expand Down
2 changes: 1 addition & 1 deletion raphtory/src/arrow/graph_impl/edge_storage_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use crate::{
edges::edge_storage_ops::{EdgeStorageOps, TimeIndexRef},
tprop_storage_ops::TPropOps,
},
prelude::TimeIndexEntry,
};
use raphtory_api::core::storage::timeindex::TimeIndexEntry;
use raphtory_arrow::{edge::Edge, tprops::ArrowTProp};
use rayon::prelude::*;
use std::{iter, ops::Range};
Expand Down
1 change: 0 additions & 1 deletion raphtory/src/arrow/graph_impl/graph_ops.rs

This file was deleted.

5 changes: 4 additions & 1 deletion raphtory/src/arrow/graph_impl/interop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use crate::{
};
use itertools::Itertools;
use polars_arrow::array::Array;
use raphtory_api::core::entities::{EID, VID};
use raphtory_api::core::{
entities::{EID, VID},
storage::timeindex::TimeIndexEntry,
};
use raphtory_arrow::interop::GraphLike;

impl GraphLike<TimeIndexEntry> for Graph {
Expand Down
2 changes: 0 additions & 2 deletions raphtory/src/arrow/graph_impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ pub mod const_properties_ops;
pub mod core_ops;
pub mod edge_filter_ops;
mod edge_storage_ops;
pub mod graph_ops;

mod interop;
pub mod layer_ops;
mod list_ops;
Expand Down
2 changes: 1 addition & 1 deletion raphtory/src/arrow/graph_impl/time_index_into_ops.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::{
core::storage::timeindex::{TimeIndexIntoOps, TimeIndexOps},
db::api::view::IntoDynBoxed,
prelude::TimeIndexEntry,
};
use raphtory_api::core::storage::timeindex::TimeIndexEntry;
use raphtory_arrow::{
prelude::{ArrayOps, BaseArrayOps},
timestamps::TimeStamps,
Expand Down
1 change: 1 addition & 0 deletions raphtory/src/arrow/graph_impl/time_semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::{
prelude::*,
};
use itertools::Itertools;
use raphtory_api::core::storage::timeindex::TimeIndexEntry;
use rayon::prelude::*;
use std::{iter, ops::Range};

Expand Down
3 changes: 2 additions & 1 deletion raphtory/src/arrow/graph_impl/tprops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use crate::{
},
core::storage::timeindex::TimeIndexIntoOps,
db::api::{storage::tprop_storage_ops::TPropOps, view::IntoDynBoxed},
prelude::{Prop, TimeIndexEntry},
prelude::Prop,
};
use raphtory_api::core::storage::timeindex::TimeIndexEntry;
use raphtory_arrow::{
chunked_array::{col::ChunkedPrimitiveCol, utf8_col::StringCol},
edge::Edge,
Expand Down
2 changes: 1 addition & 1 deletion raphtory/src/arrow/storage_interface/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::{
storage::timeindex::TimeIndexOps,
},
db::api::storage::edges::edge_storage_ops::EdgeStorageIntoOps,
prelude::TimeIndexEntry,
};
use raphtory_api::core::storage::timeindex::TimeIndexEntry;
use raphtory_arrow::{edge::Edge, edges::Edges, graph::TemporalGraph, timestamps::TimeStamps};
use std::ops::Range;

Expand Down
5 changes: 5 additions & 0 deletions raphtory/src/core/entities/graph/tgraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@ impl TemporalGraph {
self.node_meta.get_node_type_name_by_id(node.node_type)
}

pub(crate) fn node_type_id(&self, v: VID) -> usize {
let node = self.storage.get_node(v);
node.node_type
}

pub(crate) fn get_all_node_types(&self) -> Vec<ArcStr> {
self.node_meta.get_all_node_types()
}
Expand Down
2 changes: 1 addition & 1 deletion raphtory/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ extern crate core;

pub mod entities;
pub mod state;
pub(crate) mod storage;
pub mod storage;
pub mod utils;

// this is here because Arc<str> annoyingly doesn't implement all the expected comparisons
Expand Down
1 change: 1 addition & 0 deletions raphtory/src/core/storage/timeindex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
use chrono::{DateTime, NaiveDateTime, Utc};
use itertools::Itertools;
use num_traits::Saturating;
use raphtory_api::core::entities::VID;
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use std::{
Expand Down
2 changes: 1 addition & 1 deletion raphtory/src/db/api/storage/edges/edge_owned_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use crate::{
},
tprop_storage_ops::TPropOps,
},
prelude::TimeIndexEntry,
};
use raphtory_api::core::storage::timeindex::TimeIndexEntry;
use rayon::iter::ParallelIterator;
use std::ops::Range;

Expand Down
Loading
Loading