use std::collections::HashMap; use oxigraph::model::NamedNode; use oxigraph::sparql::results::{QueryResultsFormat, QueryResultsParser, SliceQueryResultsParserOutput}; use gl_inference::tonic::transport::Channel; use gl_inference::proto::ontology_client::OntologyClient; use gl_inference::proto::OntologyQueryRequest; use gl_search::{Field, OwnedValue, Schema}; use crate::class::Class; use crate::{curie, CurieHelper}; use crate::helpers::{term_as_str, term_to_named_node}; use crate::language::LanguageCondition; pub async fn index_ontology( client: &mut OntologyClient, language: &LanguageCondition, ) -> crate::Result>> { let curie_helper = CurieHelper::new((&*curie::PREFIXES).clone()); let label_filter = language.to_filter_expression("label"); let description_filter = language.to_filter_expression("description"); let mut request = OntologyQueryRequest::default(); request.sparql_query = format!(r#"PREFIX rdf: PREFIX rdfs: PREFIX skos: SELECT ?class ?subject ?label ?description WHERE {{ VALUES ?class {{ rdf:Property rdfs:Class skos:Concept }} ?subject a ?class ; rdfs:label ?label . {label_filter} OPTIONAL {{ ?subject rdfs:comment ?comment }} OPTIONAL {{ ?subject skos:definition ?definition }} BIND(COALESCE(?definition, ?comment) AS ?description) {description_filter} }}"#); let response = client.query(request).await.unwrap(); let parser_output = QueryResultsParser::from_format(QueryResultsFormat::Json) .for_slice(&response.get_ref().results) .unwrap(); let mut results = Vec::new(); if let SliceQueryResultsParserOutput::Solutions(solutions) = parser_output { let primary_language = language.primary_language(); let label_field = Schema::field("label", primary_language); let definition_field = Schema::field("definition", primary_language); for solution in solutions.filter_map(Result::ok) { let mut document = HashMap::with_capacity(4); let discriminant = solution .get("class") .and_then(term_to_named_node) .and_then(Class::try_from_named_node) .map(|doc_type| doc_type as u64) .map(OwnedValue::U64) .unwrap_or(OwnedValue::Null); document.insert(Schema::discriminant_field(), discriminant); let subject_str = solution .get("subject") .and_then(term_to_named_node) .map(NamedNode::as_str); let curie = subject_str .and_then(|subject| curie_helper.abbreviate(None, subject)) .map(OwnedValue::Str) .unwrap_or(OwnedValue::Null); document.insert(Schema::curie_field(), curie); let subject = subject_str .map(OwnedValue::from) .unwrap_or(OwnedValue::Null); document.insert(Schema::iri_field(), subject); let label = solution .get("label") .and_then(term_as_str) .map(OwnedValue::from) .unwrap_or(OwnedValue::Null); document.insert(label_field, label); let definition = solution .get("description") .and_then(term_as_str) .map(OwnedValue::from) .unwrap_or(OwnedValue::Null); document.insert(definition_field, definition); results.push(document); } } Ok(results) }