raphtory-graphql 0.11.1

Raphtory GraphQL server
Documentation
use crate::model::algorithms::{
    algorithm::Algorithm, document::GqlDocument, global_plugins::GlobalPlugins,
};
use async_graphql::{
    dynamic::{FieldValue, ResolverContext, TypeRef},
    FieldResult,
};
use dynamic_graphql::internal::TypeName;
use futures_util::future::BoxFuture;
use raphtory::vectors::{embeddings::openai_embedding, vectorised_cluster::VectorisedCluster};
use std::ops::Deref;

pub(crate) struct GlobalSearch;

impl<'a> Algorithm<'a, GlobalPlugins> for GlobalSearch {
    type OutputType = GqlDocument;
    fn output_type() -> TypeRef {
        TypeRef::named_nn_list_nn(GqlDocument::get_type_name())
    }
    fn args<'b>() -> Vec<(&'b str, TypeRef)> {
        vec![
            ("query", TypeRef::named_nn(TypeRef::STRING)),
            ("limit", TypeRef::named_nn(TypeRef::INT)),
        ]
    }
    fn apply_algo<'b>(
        entry_point: &GlobalPlugins,
        ctx: ResolverContext,
    ) -> BoxFuture<'b, FieldResult<Option<FieldValue<'b>>>> {
        let query = ctx
            .args
            .try_get("query")
            .unwrap()
            .string()
            .unwrap()
            .to_owned();
        let limit = ctx.args.try_get("limit").unwrap().u64().unwrap() as usize;
        let vectorised_graphs = entry_point.vectorised_graphs.clone();

        Box::pin(async move {
            let embedding = openai_embedding(vec![query.clone()]).await.remove(0);
            println!("running global search for {query}");

            let graphs = vectorised_graphs.read();

            let cluster = VectorisedCluster::new(graphs.deref());
            let documents = cluster.search_graph_documents(&embedding, limit, None); // TODO: add window

            let gql_documents = documents
                .into_iter()
                .map(|doc| FieldValue::owned_any(GqlDocument::from(doc)));
            Ok(Some(FieldValue::list(gql_documents)))
        })
    }
}