Skip to content

Commit

Permalink
fix(api): Fix entities types filter
Browse files Browse the repository at this point in the history
  • Loading branch information
cvauclair committed Jan 8, 2025
1 parent dfe315b commit 0a32550
Show file tree
Hide file tree
Showing 4 changed files with 274 additions and 65 deletions.
22 changes: 16 additions & 6 deletions api/schema.graphql
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
input AttributeFilter {
valueType: ValueType
}

"""Entity object"""
type Entity {
"""Entity ID"""
Expand All @@ -19,16 +23,22 @@ type Entity {
types: [Entity!]!

"""Attributes of the entity"""
attributes: [Triple!]!
attributes(filter: AttributeFilter): [Triple!]!

"""Relations outgoing from the entity"""
relations: [Relation!]!
}

"""Entity filter input object"""
input EntityFilter {
"""Filter by entity types"""
types: [String!]
input EntityAttributeFilter {
attribute: String!
value: String
valueType: ValueType
}

input EntityWhereFilter {
spaceId: String
typesContain: [String!]
attributesContain: [EntityAttributeFilter!]
}

type Options {
Expand All @@ -44,7 +54,7 @@ type Query {
"""
Returns multiple entities according to the provided space ID and filter
"""
entities(spaceId: String!, filter: EntityFilter): [Entity!]!
entities(where: EntityWhereFilter): [Entity!]!

"""Returns a single relation identified by its ID and space ID"""
relation(id: String!, spaceId: String!): Relation
Expand Down
100 changes: 86 additions & 14 deletions api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,26 @@ impl Query {
async fn entities<'a, S: ScalarValue>(
&'a self,
executor: &'a Executor<'_, '_, KnowledgeGraph, S>,
space_id: String,
// version_id: Option<String>,
filter: Option<EntityFilter>,
r#where: Option<EntityWhereFilter>,
) -> Vec<Entity> {
// let query = QueryMapper::default().select_root_node(&id, &executor.look_ahead()).build();
// tracing::info!("Query: {}", query);

Check warning on line 56 in api/src/main.rs

View workflow job for this annotation

GitHub Actions / stable / fmt

Diff in /home/runner/work/kg-node/kg-node/api/src/main.rs

match filter {
Some(EntityFilter { types: Some(types) }) if !types.is_empty() => {
mapping::Entity::<mapping::Triples>::find_by_types(
match r#where {
Some(r#where) => {
mapping::Entity::<mapping::Triples>::find_many(
&executor.context().0.neo4j,
&types,
&space_id,
Some(r#where.into())
)
.await
.expect("Failed to find entities")
.into_iter()
.map(Entity::from)
.collect::<Vec<_>>()
}
_ => mapping::Entity::<mapping::Triples>::find_all(
_ => mapping::Entity::<mapping::Triples>::find_many(
&executor.context().0.neo4j,
&space_id,
None
)
.await
.expect("Failed to find entities")
Expand Down Expand Up @@ -135,10 +132,59 @@ impl Query {
}

Check warning on line 132 in api/src/main.rs

View workflow job for this annotation

GitHub Actions / stable / fmt

Diff in /home/runner/work/kg-node/kg-node/api/src/main.rs

/// Entity filter input object
///
/// ```graphql
/// query {
/// entities(where: {
/// space_id: "BJqiLPcSgfF8FRxkFr76Uy",
/// types_contain: ["XG26vy98XAA6cR6DosTALk", "XG26vy98XAA6cR6DosTALk"],
/// attributes_contain: [
/// {id: "XG26vy98XAA6cR6DosTALk", value: "value", value_type: TEXT},
/// ]
/// })

Check warning on line 144 in api/src/main.rs

View workflow job for this annotation

GitHub Actions / stable / fmt

Diff in /home/runner/work/kg-node/kg-node/api/src/main.rs
/// }
/// ```
///
#[derive(Debug, GraphQLInputObject)]
struct EntityFilter {
/// Filter by entity types
types: Option<Vec<String>>,
r#where: Option<EntityWhereFilter>,
}

#[derive(Debug, GraphQLInputObject)]
struct EntityWhereFilter {
space_id: Option<String>,
types_contain: Option<Vec<String>>,
attributes_contain: Option<Vec<EntityAttributeFilter>>,
}

impl Into<mapping::entity::EntityWhereFilter> for EntityWhereFilter {
fn into(self) -> mapping::entity::EntityWhereFilter {
mapping::entity::EntityWhereFilter {
space_id: self.space_id,
types_contain: self.types_contain,
attributes_contain: self
.attributes_contain
.map(|filters| filters.into_iter().map(|f| f.into()).collect()),
}
}
}

#[derive(Debug, GraphQLInputObject)]
struct EntityAttributeFilter {
attribute: String,
value: Option<String>,
value_type: Option<ValueType>,
}

impl Into<mapping::entity::EntityAttributeFilter> for EntityAttributeFilter {
fn into(self) -> mapping::entity::EntityAttributeFilter {
mapping::entity::EntityAttributeFilter {
attribute: self.attribute,
value: self.value,
value_type: self.value_type.map(|vt| vt.into()),
}
}
}

/// Relation filter input object
Expand Down Expand Up @@ -272,8 +318,16 @@ impl Entity {
}

/// Attributes of the entity

Check warning on line 320 in api/src/main.rs

View workflow job for this annotation

GitHub Actions / stable / fmt

Diff in /home/runner/work/kg-node/kg-node/api/src/main.rs
fn attributes(&self) -> &[Triple] {
&self.attributes
fn attributes(&self, filter: Option<AttributeFilter>) -> Vec<&Triple> {
match filter {
Some(AttributeFilter { value_type: Some(value_type) }) => {
self.attributes
.iter()
.filter(|triple| triple.value_type == value_type)
.collect::<Vec<_>>()
}
_ => self.attributes.iter().collect::<Vec<_>>(),
}
}

/// Relations outgoing from the entity
Expand Down Expand Up @@ -307,6 +361,24 @@ impl From<mapping::ValueType> for ValueType {
}
}

impl Into<mapping::ValueType> for ValueType {
fn into(self) -> mapping::ValueType {
match self {
Self::Text => mapping::ValueType::Text,
Self::Number => mapping::ValueType::Number,
Self::Checkbox => mapping::ValueType::Checkbox,
Self::Url => mapping::ValueType::Url,
Self::Time => mapping::ValueType::Time,
Self::Point => mapping::ValueType::Point,
}
}
}

#[derive(Debug, GraphQLInputObject)]
struct AttributeFilter {
value_type: Option<ValueType>,
}

#[derive(Debug)]
pub struct Relation {
id: String,
Expand Down Expand Up @@ -516,7 +588,7 @@ impl Triple {
}
}

#[derive(Debug, GraphQLEnum)]
#[derive(Debug, GraphQLEnum, PartialEq)]
pub enum ValueType {
Text,
Number,
Expand Down
Loading

0 comments on commit 0a32550

Please sign in to comment.