.
This commit is contained in:
+51
-52
@@ -9,7 +9,8 @@ use std::fmt::Display;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::LazyLock;
|
||||
use oxigraph::store::Store;
|
||||
use crate::rdf::materialize;
|
||||
use tracing::{info, instrument};
|
||||
use crate::rdf::{conversion, materialize};
|
||||
|
||||
static PREFIXES: LazyLock<BTreeMap<String, String>> = LazyLock::new(|| {
|
||||
BTreeMap::from_iter([
|
||||
@@ -57,7 +58,7 @@ impl OntologyBuilder {
|
||||
}
|
||||
|
||||
pub fn build(self) -> error::Result<Ontology> {
|
||||
let store = if let Some(path) = self.path {
|
||||
let mut store = if let Some(path) = self.path {
|
||||
Store::open(path)
|
||||
} else {
|
||||
Store::new()
|
||||
@@ -68,41 +69,40 @@ impl OntologyBuilder {
|
||||
.map(|(k, v)| (k.to_string(), v.to_string()))
|
||||
.collect::<HashMap<String, String>>();
|
||||
|
||||
let store = materialize::same_as(store)?;
|
||||
//materialize::super_classes(&mut dataset);
|
||||
materialize::same_as(&mut store)?;
|
||||
materialize::super_classes(&mut store)?;
|
||||
store.optimize()?;
|
||||
|
||||
// Full-text search index field names
|
||||
//let fields = Self::fields(&dataset);
|
||||
let fields = Self::fields(&store)?;
|
||||
|
||||
/*let mut entities: HashMap<NamedNode, Entity> = HashMap::new();
|
||||
let entity_iris = Self::subclass_of(&dataset, gl::ENTITY)
|
||||
.chain(Self::subclass_of(&dataset, rda::ENTITY))
|
||||
.chain([
|
||||
rdf::PROPERTY.into_owned(),
|
||||
rdfs::CLASS.into_owned(),
|
||||
]);
|
||||
|
||||
for iri in entity_iris {
|
||||
let subject = iri.as_ref().into();
|
||||
|
||||
let label = dataset.quads_for_pattern(Some(subject), Some(rdfs::LABEL), None, None)
|
||||
.filter_map(|quad| term_to_string(&quad.object.into_owned()).map(String::from))
|
||||
let mut entities: HashMap<NamedNode, Entity> = 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)
|
||||
.filter_map(|quad| conversion::term_to_string(&quad.object).map(String::from))
|
||||
.next();
|
||||
|
||||
let catalog_id = dataset.quads_for_pattern(Some(subject), Some(gl::CATALOG_ID), None, None)
|
||||
.filter_map(|quad| term_to_u64(&quad.object.into_owned()))
|
||||
let comment = store.quads_for_pattern(Some(quad.subject.as_ref().into()), Some(rdfs::COMMENT), None, None)
|
||||
.filter_map(Result::ok)
|
||||
.filter_map(|quad| conversion::term_to_string(&quad.object).map(String::from))
|
||||
.next();
|
||||
|
||||
if let Some(catalog_id) = catalog_id {
|
||||
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 dataset.quads_for_pattern(Some(subject), Some(gl::ASSOCIATED_PROPERTY), None, None) {
|
||||
if let NamedOrBlankNodeRef::NamedNode(subject) = quad.subject
|
||||
&& let TermRef::NamedNode(property) = quad.object {
|
||||
properties.insert(property.into_owned());
|
||||
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(iri, Entity {
|
||||
label: label.unwrap_or(catalog_id.to_string()),
|
||||
entities.insert(subject, Entity {
|
||||
label,
|
||||
comment,
|
||||
catalog_id,
|
||||
properties,
|
||||
});
|
||||
@@ -110,28 +110,25 @@ impl OntologyBuilder {
|
||||
}
|
||||
|
||||
let mut indexed_by = HashMap::new();
|
||||
for quad in dataset.quads_for_pattern(None, Some(gl::INDEXED_BY_FIELD), None, None) {
|
||||
if let NamedOrBlankNodeRef::NamedNode(subject) = quad.subject
|
||||
&& let TermRef::NamedNode(field) = quad.object
|
||||
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
|
||||
{
|
||||
indexed_by.insert(subject.into_owned(), field.into_owned());
|
||||
indexed_by.insert(subject, field);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
Ok(Ontology {
|
||||
store,
|
||||
prefixes,
|
||||
fields: HashMap::new(),
|
||||
entities: HashMap::from_iter([(rdf::PROPERTY.into_owned(), Entity {
|
||||
label: "property".to_string(),
|
||||
catalog_id: 0,
|
||||
properties: HashSet::new(),
|
||||
})]),
|
||||
indexed_by: HashMap::new(),
|
||||
fields,
|
||||
entities,
|
||||
indexed_by,
|
||||
})
|
||||
}
|
||||
|
||||
/*fn fields(dataset: &Dataset) -> HashMap<NamedNode, IndexField> {
|
||||
fn fields(store: &Store) -> error::Result<HashMap<NamedNode, IndexField>> {
|
||||
let query = SparqlEvaluator::new()
|
||||
.parse_query(
|
||||
r#"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||
@@ -147,13 +144,12 @@ SELECT DISTINCT ?subject ?name ?label {
|
||||
.expect("Unable to parse field query");
|
||||
|
||||
let mut results = HashMap::new();
|
||||
if let QueryResults::Solutions(solutions) =
|
||||
query.on_queryable_dataset(dataset).execute().unwrap()
|
||||
if let QueryResults::Solutions(solutions) = query.on_store(store).execute()?
|
||||
{
|
||||
for solution in solutions.filter_map(Result::ok) {
|
||||
let subject = solution.get("subject").and_then(term_to_named_node);
|
||||
let name = solution.get("name").and_then(term_to_string);
|
||||
let label = solution.get("label").and_then(term_to_string);
|
||||
let subject = solution.get("subject").and_then(conversion::term_to_named_node);
|
||||
let name = solution.get("name").and_then(conversion::term_to_string);
|
||||
let label = solution.get("label").and_then(conversion::term_to_string);
|
||||
|
||||
if let Some(subject) = subject && let Some(name) = name {
|
||||
let field = IndexField {
|
||||
@@ -164,10 +160,10 @@ SELECT DISTINCT ?subject ?name ?label {
|
||||
}
|
||||
}
|
||||
}
|
||||
results
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
fn subclass_of(dataset: &Dataset, class: NamedNodeRef<'_>) -> impl Iterator<Item = NamedNode> {
|
||||
/*fn subclass_of(dataset: &Dataset, class: NamedNodeRef<'_>) -> impl Iterator<Item = NamedNode> {
|
||||
let query = SparqlEvaluator::new()
|
||||
.parse_query(
|
||||
format!(
|
||||
@@ -200,6 +196,7 @@ SELECT ?class {{
|
||||
pub struct LabeledIri {
|
||||
pub iri: NamedNode,
|
||||
pub label: String,
|
||||
pub comment: Option<String>,
|
||||
}
|
||||
|
||||
impl PartialEq for LabeledIri {
|
||||
@@ -225,6 +222,7 @@ pub struct IriInformation {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Entity {
|
||||
pub label: String,
|
||||
pub comment: Option<String>,
|
||||
pub catalog_id: u64,
|
||||
pub properties: HashSet<NamedNode>,
|
||||
}
|
||||
@@ -263,11 +261,6 @@ impl Ontology {
|
||||
&*PREFIXES
|
||||
}
|
||||
|
||||
/*pub fn info(&self, node: NamedNodeRef<'_>) -> Option<&IriInformation> {
|
||||
let node = node.into_owned();
|
||||
self.iri_info.get(&node)
|
||||
}*/
|
||||
|
||||
pub fn abbreviate(&self, node: NamedNodeRef<'_>) -> String {
|
||||
for (prefix_name, prefix_iri) in &self.prefixes {
|
||||
if let Some(local_name) = node.as_str().strip_prefix(prefix_iri) {
|
||||
@@ -314,6 +307,7 @@ impl Ontology {
|
||||
.map(|entity| LabeledIri {
|
||||
iri: class.to_owned(),
|
||||
label: entity.label.to_owned(),
|
||||
comment: entity.comment.to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -322,9 +316,14 @@ impl Ontology {
|
||||
.map(|(iri, entity)| LabeledIri {
|
||||
iri: iri.to_owned(),
|
||||
label: entity.label.to_owned(),
|
||||
comment: entity.comment.to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn entities(&self) -> impl Iterator<Item = (&NamedNode, &Entity)> {
|
||||
self.entities.iter()
|
||||
}
|
||||
|
||||
pub fn datatypes(&self) -> impl Iterator<Item = NamedNode> {
|
||||
self.store
|
||||
.quads_for_pattern(
|
||||
|
||||
Reference in New Issue
Block a user