19

I've to get all the instances of a class C and subclasses (direct or indirect) of C, in SPARQL.

I can get all the direct subclasses of C in this way:

SELECT ?entity
WHERE {
  ?subclass rdfs:subClassOf :C .
  ?entity rdf:type ?subclass .
}

But I can't get the instances of an indirect subclass and neither any instance of C.

As I know (I've pre-calculated them) all the subclasses (direct and indirect of C), and I can build a dynamic query, is it possible build a query like the following one?

SELECT ?entity
WHERE {
  ?entity rdf:type in <list>.
}

Thanks to everyone.

EDIT:

I've just solved it, even if in a not elegant way.

SELECT ?entity
WHERE {
  { ?entity rdf:type :C }
  UNION { ?entity rdf:type :SubClass1 }
  UNION { ?entity rdf:type :SubClass2 }
  UNION { ?entity rdf:type :SubClass3 }
}
auino
  • 1,644
  • 5
  • 23
  • 43

3 Answers3

41

A better solution is to use property path expressions in SPARQL 1.1

This would be rewritten as:

SELECT ?entity
WHERE {
  ?entity rdf:type ?type.
  ?type rdfs:subClassOf* :C.
}
William Greenly
  • 3,914
  • 20
  • 18
  • 2
    Depending on the triple store this might or might not work. Not all triple stores implement property paths expressions. – Manuel Salvadores Feb 09 '12 at 19:40
  • @msalvadores As an update, while there still may be older triple stores, property paths made it into SPARQL 1.1, so any triple stores that support the current standard will support property paths. – Joshua Taylor Jan 13 '14 at 13:57
  • This is elegant, but will only work if all the (sub-)classes are in the default graph. Property paths do now do not work over named graph boundaries. – Martynas Jusevičius Aug 20 '20 at 09:13
  • This answer is probably outdated? I had to use Robin Keskirarkka's syntax. – Cris Nov 05 '22 at 12:32
12

Based on the SPARQL 1.1 specification the proper way to do it would be:

SELECT ?entity
WHERE {
    ?entity rdf:type/rdfs:subClassOf* :C
}

Without support for property paths there is no way of expressing class hierarchies of arbitrary length.

0

For completeness, these days, if the graph has basic RDFS inferencing (or better) available, you can do a direct query:

SELECT ?entity
WHERE {
    ?entity rdf:type :C
}

Technically, this means no property path required, but all relevant SPARQL query engines today are at least 1.1 if not RDF* compliant.

If using an engine that preprocesses the inference calculations and depending on the depth of the class hierarchy, this solution is generally faster than the previous solutions.

AtesComp
  • 431
  • 3
  • 5