Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix vocprez queries to support inverse skos relationships #161

Merged
merged 4 commits into from
Oct 11, 2023

Conversation

edmondchuc
Copy link
Collaborator

@edmondchuc edmondchuc commented Oct 10, 2023

The current set of vocprez queries to provide progressive loading of very large vocabs only supports skos:hasTopConcept and skos:broader relationships. This PR adds support for the same relationships and its inverse relationships, skos:topConceptOf and skos:narrower.

Fixes #162.

@edmondchuc
Copy link
Collaborator Author

A test is skipped because the combination of the data and the generated query results in an exception in RDFLib's SPARQL processor.

Generated query
PREFIX prez: <https://prez.dev/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>

CONSTRUCT {
  ?concept skos:prefLabel ?label .
  ?concept prez:childrenCount ?narrowerChildrenCount .
  ?iri prez:childrenCount ?childrenCount .
  ?iri skos:hasTopConcept ?concept .
  ?iri rdf:type ?type .
  ?concept rdf:type ?conceptType .
}
WHERE {
  BIND(<http://linked.data.gov.au/def2/borehole-purpose-no-children> as ?iri)
  OPTIONAL {
    ?iri skos:hasTopConcept ?concept .
    ?concept skos:prefLabel ?label .
  }
  OPTIONAL {
    ?concept skos:topConceptOf ?iri .
    ?concept skos:prefLabel ?label .
  }
  ?iri rdf:type ?type .
  ?concept rdf:type ?conceptType .

  {
    SELECT (COUNT(?childConcept) AS ?childrenCount)
    WHERE {
      BIND(<http://linked.data.gov.au/def2/borehole-purpose-no-children> as ?iri)
      ?iri skos:hasTopConcept ?childConcept .
    }
  }

  {
    SELECT ?concept ?label (COUNT(?narrowerConcept) AS ?narrowerChildrenCount)
    WHERE {
      BIND(<http://linked.data.gov.au/def2/borehole-purpose-no-children> as ?iri)
      OPTIONAL {
        ?iri skos:hasTopConcept ?concept .
        ?concept skos:prefLabel ?label .
      }
      OPTIONAL {
        ?concept skos:topConceptOf ?iri .
        ?concept skos:prefLabel ?label .
      }

      OPTIONAL {
        ?narrowerConcept skos:broader ?concept .
      }
      OPTIONAL {
        ?concept skos:narrower ?narrowerConcept .
      }
    }
    GROUP BY ?concept ?label
    ORDER BY str(?label)
    LIMIT 20
    OFFSET 0
  }
}

Traceback
Traceback (most recent call last):
  File "/Users/edmondchuc/projects/prez/tests/local_sparql_store/store.py", line 178, in apply_sparql_query
    result = vocprez_graph.query(new_query)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/graph.py", line 1567, in query
    return result(processor.query(query_object, initBindings, initNs, **kwargs))  # type: ignore[arg-type]
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/processor.py", line 140, in query
    return evalQuery(self.graph, query, initBindings, base)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 695, in evalQuery
    return evalPart(ctx, main)
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 323, in evalPart
    return evalConstructQuery(ctx, part)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 597, in evalConstructQuery
    for c in evalPart(ctx, query.p):
             ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 303, in evalPart
    return evalProject(ctx, part)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 561, in evalProject
    res = evalPart(ctx, project.p)
          ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 288, in evalPart
    return evalJoin(ctx, part)
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 156, in evalJoin
    b = set(evalPart(ctx, join.p2))
            ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 296, in evalPart
    return evalMultiset(ctx, part)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 266, in evalMultiset
    return evalPart(ctx, part.p)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 305, in evalPart
    return evalSlice(ctx, part)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 499, in evalSlice
    res = evalPart(ctx, slice.p)
          ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 303, in evalPart
    return evalProject(ctx, part)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 561, in evalProject
    res = evalPart(ctx, project.p)
          ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 312, in evalPart
    return evalOrderBy(ctx, part)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/edmondchuc/projects/prez/venv/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py", line 491, in evalOrderBy
    res = sorted(
          ^^^^^^^
TypeError: '<' not supported between instances of 'NoneType' and 'NoneType'


@edmondchuc edmondchuc merged commit 570701e into main Oct 11, 2023
1 check passed
@edmondchuc edmondchuc deleted the edmond/fix-vocprez-progressive-loading branch October 11, 2023 01:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

Concept hierarchies only defined with narrowers
2 participants