Warm tip: This article is reproduced from serverfault.com, please click

Finding classes which should be instances sparql; Finding classes with exactly 1 subclass

发布于 2021-02-01 15:13:00

It sounds quite simple but I have not managed to find a nice solution yet. I'm looking to find the classes in my ontology which have exactly one subclass.

So far I have approached it as follows:

SELECT (COUNT(?anything) AS ?count) ?class
WHERE {
GRAPH <> {

    ?class rdf:type owl:Class.
    ?class rdfs:subClassOf ?anything.
    ?anything rdf:type owl:Class.
   
} group by ?class 

I should then theoretically be able to sort on count, and the results that have value 1 should have only have 1 subclass. However, when I execute this query, the counts do not correspond with what I expect at all e.g. my test case should return 1, which it does, but another class which doesn't have a subclass at all, also returns 1. And a class with 3 subclasses returns a count of 4.

in the image below, it should find that the highlighted classes have a count of 1. picture of class structure

Questioner
Robin
Viewed
11
Joshua Taylor 2021-02-02 04:48:16

The SPARQL query you're looking for would be something like

SELECT ?class WHERE {
  ?sub rdfs:subClassOf ?class
}
GROUP BY ?class 
HAVING (COUNT(DISTINCT ?sub) = 1)

As UninformedUser mentioned in a comment, though, if there is OWL inference available, there can be lots of answers that you might not be expecting, such as

owl:Nothing rdfs:subClassOf ex:YourClass

and

ex:YourClass rdfs:subClassOf ex:YourClass

If those keep the query from producing the kind of results you're looking for, you should add a filter like

SELECT ?class WHERE {
  ?sub rdfs:subClassOf ?class
  FILTER ( ?sub != ?class && ?sub != owl:Nothing )
}
GROUP BY ?class 
HAVING (COUNT(DISTINCT ?sub) = 1)