.
This commit is contained in:
+36
-30
@@ -2,11 +2,12 @@ use crate::error;
|
||||
use crate::rdf::vocab::gl;
|
||||
use oxigraph::model::vocab::{rdf, rdfs, xsd};
|
||||
use oxigraph::model::{Dataset, Graph, GraphNameRef, LiteralRef, NamedNode, NamedNodeRef, NamedOrBlankNode, NamedOrBlankNodeRef, Term, TermRef, Triple, TripleRef};
|
||||
use oxigraph::sparql::{PreparedSparqlQuery, QueryResults, SparqlEvaluator};
|
||||
use oxigraph::sparql::{QueryResults, SparqlEvaluator};
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap};
|
||||
use std::fmt::Display;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::LazyLock;
|
||||
use iced::futures::TryFutureExt;
|
||||
use oxigraph::store::Store;
|
||||
use tracing::debug_span;
|
||||
use crate::rdf::{conversion, materialize};
|
||||
@@ -46,7 +47,7 @@ static PREFIXES: LazyLock<BTreeMap<String, String>> = LazyLock::new(|| {
|
||||
("rdax", "http://rdaregistry.info/Elements/x/"),
|
||||
("schema", "https://schema.org/"),
|
||||
("quill", "http://fedora.quill.lan/rest/"),
|
||||
("gl", "ONTOLOGY_PREFIX"),
|
||||
("gl", ONTOLOGY_PREFIX),
|
||||
].map(|(k, v)| (k.to_string(), v.to_string())))
|
||||
});
|
||||
|
||||
@@ -108,7 +109,7 @@ impl OntologyBuilder {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IndexEntry {
|
||||
pub catalog_id: u64,
|
||||
pub category_id: u64,
|
||||
pub fields: HashMap<String, String>,
|
||||
}
|
||||
|
||||
@@ -172,12 +173,12 @@ impl Ontology {
|
||||
.collect::<Dataset>()
|
||||
}
|
||||
|
||||
pub fn index_query(language: &LanguageCondition) -> PreparedSparqlQuery {
|
||||
pub fn index(&self, language: &LanguageCondition, source: Option<Dataset>) -> impl Future<Output = error::Result<HashMap<NamedNode, IndexEntry>>> + 'static {
|
||||
let language_filter = language.to_filter_expression("fieldValue");
|
||||
let query = format!(r#"SELECT ?individual ?catalogId ?fieldName ?fieldValue
|
||||
let query = format!(r#"SELECT ?individual ?categoryId ?fieldName ?fieldValue
|
||||
WHERE {{
|
||||
?class a gl:SearchableClass ;
|
||||
gl:catalogId ?catalogId ;
|
||||
gl:categoryId ?categoryId ;
|
||||
gl:associatedProperty ?property .
|
||||
|
||||
?property gl:indexedByField/gl:fieldName ?fieldName .
|
||||
@@ -190,39 +191,44 @@ WHERE {{
|
||||
let mut sparql = SparqlEvaluator::new()
|
||||
.with_prefix("gl", ONTOLOGY_PREFIX).unwrap()
|
||||
.parse_query(&query)
|
||||
.unwrap();
|
||||
.expect("Unable to parse query");
|
||||
sparql.dataset_mut().set_default_graph_as_union();
|
||||
sparql
|
||||
}
|
||||
|
||||
pub fn execute_query(&self, query: PreparedSparqlQuery) -> error::Result<QueryResults<'_>> {
|
||||
Ok(query.on_store(&self.store).execute()?)
|
||||
}
|
||||
let store = self.store.clone();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let _span = debug_span!("Index Query").entered();
|
||||
let query_results = if let Some(source) = &source {
|
||||
sparql.on_queryable_dataset(source).execute()
|
||||
} else {
|
||||
sparql.on_store(&store).execute()
|
||||
}.expect("Unable to execute indexing query");
|
||||
|
||||
pub fn transform_index_results(query_results: QueryResults) -> HashMap<NamedNode, IndexEntry> {
|
||||
let mut results = HashMap::new();
|
||||
if let QueryResults::Solutions(solutions) = query_results {
|
||||
for solution in solutions.filter_map(Result::ok) {
|
||||
let individual = solution.get("individual").and_then(conversion::term_to_named_node);
|
||||
let catalog_id = solution.get("catalogId").and_then(conversion::term_to_u64);
|
||||
let field_name = solution.get("fieldName").and_then(conversion::term_as_str);
|
||||
let field_value = solution.get("fieldValue").and_then(conversion::term_as_str);
|
||||
if let (Some(individual), Some(catalog_id), Some(field_name), Some(field_value)) = (individual, catalog_id, field_name, field_value) {
|
||||
results.entry(individual.to_owned())
|
||||
.and_modify(|entry: &mut IndexEntry| {
|
||||
entry.fields.insert(field_name.to_owned(), field_value.to_owned());
|
||||
}).or_insert(IndexEntry {
|
||||
catalog_id,
|
||||
let mut results = HashMap::new();
|
||||
if let QueryResults::Solutions(solutions) = query_results {
|
||||
for solution in solutions.filter_map(Result::ok) {
|
||||
let individual = solution.get("individual").and_then(conversion::term_to_named_node);
|
||||
let catalog_id = solution.get("categoryId").and_then(conversion::term_to_u64);
|
||||
let field_name = solution.get("fieldName").and_then(conversion::term_as_str);
|
||||
let field_value = solution.get("fieldValue").and_then(conversion::term_as_str);
|
||||
if let (Some(individual), Some(catalog_id), Some(field_name), Some(field_value)) = (individual, catalog_id, field_name, field_value) {
|
||||
results.entry(individual.to_owned())
|
||||
.and_modify(|entry: &mut IndexEntry| {
|
||||
entry.fields.insert(field_name.to_owned(), field_value.to_owned());
|
||||
}).or_insert(IndexEntry {
|
||||
category_id: catalog_id,
|
||||
fields: HashMap::from_iter([(field_name.to_owned(), field_value.to_owned())]),
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
results
|
||||
results
|
||||
}).map_err(error::Error::from)
|
||||
}
|
||||
|
||||
pub fn catalog_id(&self, class: &NamedNode) -> Option<u64> {
|
||||
self.store.quads_for_pattern(Some(class.into()), Some(gl::CATALOG_ID), None, None)
|
||||
pub fn category_id(&self, class: &NamedNode) -> Option<u64> {
|
||||
self.store.quads_for_pattern(Some(class.into()), Some(gl::CATEGORY_ID), None, None)
|
||||
.filter_map(Result::ok)
|
||||
.map(conversion::quad_into_term)
|
||||
.filter_map(conversion::term_into_u64)
|
||||
|
||||
@@ -7,8 +7,8 @@ pub mod gl {
|
||||
pub const INDEXED_BY_FIELD: NamedNodeRef =
|
||||
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/indexedByField");
|
||||
|
||||
pub const CATALOG_ID: NamedNodeRef =
|
||||
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/catalogId");
|
||||
pub const CATEGORY_ID: NamedNodeRef =
|
||||
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/categoryId");
|
||||
|
||||
pub const SEARCHABLE_CLASS: NamedNodeRef =
|
||||
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/SearchableClass");
|
||||
|
||||
Reference in New Issue
Block a user