From 038afc464528c6679106c184b685b6151a6ac970bde4f3cd9ae8364b2efd323a Mon Sep 17 00:00:00 2001 From: Alex Wied <543423+centromere@users.noreply.github.com> Date: Wed, 1 Jul 2026 21:28:12 -0400 Subject: [PATCH] . --- publish/src/app.rs | 10 ++--- publish/src/rdf/conversion.rs | 5 ++- publish/src/rdf/ontology.rs | 75 +++++------------------------------ search/src/schema.rs | 5 +++ 4 files changed, 24 insertions(+), 71 deletions(-) diff --git a/publish/src/app.rs b/publish/src/app.rs index 0aef864..80a72b4 100644 --- a/publish/src/app.rs +++ b/publish/src/app.rs @@ -44,7 +44,7 @@ pub(crate) enum Message { UnhoverRow(QuadKey), QueryUpdated(String), SetSearchResults(Vec), - QueryTypeUpdated(NamedNode), + QueryTypeUpdated(LabeledIri), SearchResultClicked(NamedNode), DatatypeUpdated(QuadKey, Option), LanguageUpdated(QuadKey, Option), @@ -117,6 +117,7 @@ impl Publisher { let mut document = doc!( Schema::type_field() => entry.catalog_id, Schema::iri_field() => individual.as_str(), + Schema::curie_field() => ontology.abbreviate(individual.as_ref()), ); for (key, value) in entry.fields { document.add_text(Schema::field(&key, language::ENGLISH_PRIMARY), value.as_str()); @@ -328,9 +329,8 @@ impl Publisher { } Message::QueryTypeUpdated(type_) => { if let Some(search_state) = &mut self.search_state { - if let Some(type_) = self.ontology.labeled_entity(&type_) { - search_state.type_ = type_; - } + search_state.type_ = type_; + task = Task::done(Message::QueryUpdated(search_state.query.clone())); } } Message::QueryUpdated(new_query) => { @@ -676,7 +676,7 @@ impl Publisher { entities.sort_by(|a, b| Ord::cmp(&a.label, &b.label)); let type_selector = pick_list(Some(&search_state.type_), entities, ToString::to_string) - .on_select(|selection| Message::QueryTypeUpdated(selection.iri)); + .on_select(|selection| Message::QueryTypeUpdated(selection)); let fields = self.ontology.fields_for_class(&search_state.type_.iri, &*language::ENGLISH_OR_UNTAGGED) .expect("Unable to load fields for class"); diff --git a/publish/src/rdf/conversion.rs b/publish/src/rdf/conversion.rs index b930495..fcfcdea 100644 --- a/publish/src/rdf/conversion.rs +++ b/publish/src/rdf/conversion.rs @@ -1,6 +1,5 @@ use oxigraph::model::{NamedNode, Quad, Term}; use oxigraph::model::vocab::{rdf, xsd}; -use oxilangtag::LanguageTag; pub fn quad_into_term(quad: Quad) -> Term { quad.object @@ -61,4 +60,8 @@ pub fn term_to_u64(term: &Term) -> Option { let value: u64 = literal.value().parse().expect("Failed to parse u64 from ontology. It ought to be a non-negative integer."); Some(value) } else { None } +} + +pub fn term_into_u64(term: Term) -> Option { + term_to_u64(&term) } \ No newline at end of file diff --git a/publish/src/rdf/ontology.rs b/publish/src/rdf/ontology.rs index 4c195b6..1523bde 100644 --- a/publish/src/rdf/ontology.rs +++ b/publish/src/rdf/ontology.rs @@ -8,11 +8,8 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use std::fmt::Display; use std::path::{Path, PathBuf}; use std::sync::LazyLock; -use iced::widget::sensor::Key; use oxigraph::store::Store; -use oxilangtag::LanguageTag; -use tracing::{debug, debug_span}; -use crate::rdf::{conversion, language, materialize}; +use crate::rdf::conversion; use crate::rdf::language::LanguageCondition; static PREFIXES: LazyLock> = LazyLock::new(|| { @@ -78,49 +75,11 @@ impl OntologyBuilder { materialize::super_classes(&mut store)?; debug_span!("Optimize Ontology").in_scope(|| store.optimize())?;*/ - let mut entities: HashMap = HashMap::new(); - // All Entities have exactly one catalog ID. - /*for quad in store.quads_for_pattern(None, Some(gl::CATALOG_ID), None, None) - .filter_map(Result::ok) { - let label = store.quads_for_pattern(Some(quad.subject.as_ref().into()), Some(rdfs::LABEL), None, None) - .filter_map(Result::ok) - .map(conversion::quad_into_term) - .filter(|term| conversion::language_matches(term, &conversion::english())) - .filter_map(conversion::term_into_string) - .next(); - - let comment = store.quads_for_pattern(Some(quad.subject.as_ref().into()), Some(rdfs::COMMENT), None, None) - .filter_map(Result::ok) - .map(conversion::quad_into_term) - .filter(|term| conversion::language_matches(term, &conversion::english())) - .filter_map(conversion::term_into_string) - .next(); - - if let Some(catalog_id) = conversion::term_to_u64(&quad.object) && - let NamedOrBlankNode::NamedNode(subject) = quad.subject && - let Some(label) = label { - let mut properties = HashSet::new(); - for quad in store.quads_for_pattern(Some(subject.as_ref().into()), Some(gl::ASSOCIATED_PROPERTY), None, None) - .filter_map(Result::ok) { - if let Term::NamedNode(property) = quad.object { - properties.insert(property); - } - } - entities.insert(subject, Entity { - label, - comment, - catalog_id, - properties, - }); - } - }*/ - let mut indexed_by = HashMap::new(); for quad in store.quads_for_pattern(None, Some(gl::INDEXED_BY_FIELD), None, None) .filter_map(Result::ok) { if let NamedOrBlankNode::NamedNode(subject) = quad.subject - && let Term::NamedNode(field) = quad.object - { + && let Term::NamedNode(field) = quad.object { indexed_by.insert(subject, field); } } @@ -128,8 +87,6 @@ impl OntologyBuilder { Ok(Ontology { store, prefixes, - entities, - indexed_by, }) } } @@ -174,12 +131,6 @@ pub struct IndexField { pub struct Ontology { store: Store, prefixes: HashMap, - - // NamedIndividual of class Entity -> Rust Type - entities: HashMap, - - // Property -> NamedIndividual of class IndexField - indexed_by: HashMap, } impl Ontology { @@ -235,6 +186,14 @@ WHERE {{ Ok(results) } + pub fn catalog_id(&self, class: &NamedNode) -> Option { + self.store.quads_for_pattern(Some(class.into()), Some(gl::CATALOG_ID), None, None) + .filter_map(Result::ok) + .map(conversion::quad_into_term) + .filter_map(conversion::term_into_u64) + .next() + } + pub fn fields_for_class(&self, class: &NamedNode, language: &LanguageCondition) -> error::Result> { let language_filter = language.to_filter_expression("label"); let query = format!(r#"SELECT DISTINCT ?name ?label {{ @@ -288,12 +247,6 @@ WHERE {{ .map(|base| NamedNode::new_unchecked(format!("{base}{name}"))) } - pub fn catalog_id(&self, class: &NamedNode) -> Option { - self.entities - .get(class) - .map(|entity| entity.catalog_id) - } - pub fn info(&self, iri: &NamedNode, language: &LanguageCondition) -> LabeledIri { let label = self.store.quads_for_pattern(Some(iri.as_ref().into()), Some(rdfs::LABEL), None, None) .filter_map(Result::ok) @@ -309,14 +262,6 @@ WHERE {{ } } - pub fn labeled_entity(&self, class: &NamedNode) -> Option { - self.entities.get(class) - .map(|entity| LabeledIri { - iri: class.to_owned(), - label: entity.label.to_owned(), - }) - } - pub fn labeled_entities(&self, language: &LanguageCondition) -> impl Iterator { self.store.quads_for_pattern(None, Some(rdf::TYPE), Some(gl::ENTITY.into()), None) .filter_map(Result::ok) diff --git a/search/src/schema.rs b/search/src/schema.rs index 0490a71..f7f8c61 100644 --- a/search/src/schema.rs +++ b/search/src/schema.rs @@ -26,6 +26,7 @@ impl Schema { let mut schema_builder = TantivySchema::builder(); schema_builder.add_u64_field("type", schema::FAST | schema::INDEXED); schema_builder.add_text_field("iri", schema::STORED | schema::STRING); + schema_builder.add_text_field("curie", stored_ngram32.clone()); schema_builder.add_text_field("label:en", stored_ngram32.clone()); schema_builder.add_text_field("definition:en", stored_en_stem.clone()); @@ -45,6 +46,10 @@ impl Schema { Self::schema().get_field("iri").unwrap() } + pub fn curie_field() -> Field { + Self::schema().get_field("curie").unwrap() + } + pub fn field(name: &str, language: &str) -> Field { Schema::schema() .get_field(&format!("{name}:{language}"))