Skip to content

SPARQL tips and tricks

Jiaru Bai edited this page Oct 29, 2021 · 2 revisions

Property paths

In 2013, SPARQL 1.1 introduced a new feature, namely "property paths", to enable compact queries. As it’s a standard feature in SPARQL 1.1, most triple stores claiming to support SPARQL 1.1 should support this as well. In that regard, this paper might also be of interest:

Skubella, Adrian, Janke, Daniel and Staab, Steffen (2019) BeSEPPI: Semantic-based benchmarking of property path implementations. The Semantic Web - 15th International Conference, Portoroz, Slovenia. 02 - 06 Jun 2019. pp. 475-490. Preprint: https://eprints.soton.ac.uk/429356/ Paper: https://doi.org/10.1007/978-3-030-21348-0_31

Below are two simple examples of how to use different syntax provided by the "property paths". There’s more functions/syntax that might be of help under this feature, for more information, please visit https://www.w3.org/TR/sparql11-query/#propertypaths.

Equivalent patterns

In the syntax of "property paths", one frequently used symbol is /, which indicates the SequencePath between concepts and it allows us to write compact queries. For example, we have a reaction conducted at a reaction condition of residence time, i.e.

PREFIX OntoRxn:    <https://github.com/cambridge-cares/TheWorldAvatar/blob/develop/JPS_Ontology/ontology/ontorxn/OntoRxn.owl#>
PREFIX exp1:       <https://theworldavatar.com/kb/ontorxn/ReactionExperiment_1/>
PREFIX rdf:        <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX om:         <http://www.ontology-of-units-of-measure.org/resource/om-2/>

exp1:RxnExp_1 
    rdf:type OntoRxn:ReactionExperiment;
    OntoRxn:hasResTime exp1:ResidenceTime_1;
.

If you are working with dimensional quantities following OM (units of measure) practices, the complete triples about exp1:ResidenceTime_1 should be:

OntoRxn:ResidenceTime rdf:type om:Duration .

exp1:ResidenceTime_1
    rdf:type OntoRxn:ResidenceTime;
    om:hasPhenomenon exp1:RxnExp_1;
    om:hasValue exp1:ResidenceTime_1_Measure_1;
.

exp1:ResidenceTime_1_Measure_1
    rdf:type om:Measure;
    om:hasUnit om:minute-Time;
    om:hasNumericalValue "8.1"^^xsd:double;
.

To retrieve the numerical value of the residence time, we normally write a SPARQL query string like:

PREFIX OntoRxn:    <https://github.com/cambridge-cares/TheWorldAvatar/blob/develop/JPS_Ontology/ontology/ontorxn/OntoRxn.owl#>
PREFIX exp1:       <https://theworldavatar.com/kb/ontorxn/ReactionExperiment_1/>
PREFIX om:         <http://www.ontology-of-units-of-measure.org/resource/om-2/>
SELECT ?res_time ?unit
WHERE {
  exp1:RxnExp_1 OntoRxn:hasResTime ?res . 
  ?res om:hasValue ?measure . 
  ?measure om:hasNumericalValue ?res_time ;
           om:hasUnit ?unit .
}

which will return results as:

res_time unit
8.1 <http://www.ontology-of-units-of-measure.org/resource/om-2/minute-Time>

The same results can be retrieved by writing compact queries using /, i.e.

PREFIX OntoRxn:    <https://github.com/cambridge-cares/TheWorldAvatar/blob/develop/JPS_Ontology/ontology/ontorxn/OntoRxn.owl#>
PREFIX exp1:       <https://theworldavatar.com/kb/ontorxn/ReactionExperiment_1/>
PREFIX om:         <http://www.ontology-of-units-of-measure.org/resource/om-2/>
SELECT ?res_time ?unit
WHERE {
  exp1:RxnExp_1 OntoRxn:hasResTime/om:hasValue ?measure . 
  ?measure om:hasNumericalValue ?res_time ;
           om:hasUnit ?unit .
}

Above is only a simple example, the SequencePath (/) will be more useful when we want to query a deep ontology.

Arbitrary-length path matching

Class and subclass

Another frequently used symbol is +, which indicates the OneOrMorePath between concepts. This is particularly useful in querying the instances within a class hierarchy. For example, we have a hierarchy of concepts and their corresponding instances about Asset, i.e.

PREFIX owl:   <http://www.w3.org/2002/07/owl#>
PREFIX xsd:   <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
PREFIX tbox:  <http://www.example.com/tbox#>
PREFIX abox:  <http://www.example.com/abox/>

# TBox class hierarchy
tbox:Asset rdf:type owl:Class . 

tbox:TangibleAsset rdfs:subClassOf tbox:Asset . 
tbox:PropertyAndPlant rdfs:subClassOf tbox:TangibleAsset . 
tbox:EcoIndustrialPark rdfs:subClassOf tbox:PropertyAndPlant . 
tbox:ChemicalPlant rdfs:subClassOf tbox:EcoIndustrialPark . 
tbox:Vehicles rdfs:subClassOf tbox:TangibleAsset . 
tbox:Car rdfs:subClassOf tbox:Vehicles . 
tbox:Flight rdfs:subClassOf tbox:Vehicles . 

tbox:IntangibleAsset rdfs:subClassOf tbox:Asset . 
tbox:Patent rdfs:subClassOf tbox:IntangibleAsset . 
tbox:PatentAtEPO rdfs:subClassOf tbox:Patent . 
tbox:PatentAtWIPO rdfs:subClassOf tbox:Patent .

# ABox instances of class hierarchy
abox:Asset_101 rdf:type tbox:Asset .
abox:TangibleAsset_101 rdf:type tbox:TangibleAsset . 
abox:Properties_101 rdf:type tbox:PropertyAndPlant . 
abox:JurongIslandPark rdf:type tbox:EcoIndustrialPark . 
abox:ChemicalPlant_101 rdf:type tbox:ChemicalPlant . 
abox:TransportVehicle_101 rdf:type tbox:Vehicles . 
abox:Bus_101 rdf:type tbox:Car . 
abox:Flight_101 rdf:type tbox:Flight . 

abox:IntangibleAsset_101 rdf:type tbox:IntangibleAsset . 
abox:FilledPatent_101 rdf:type tbox:Patent . 
abox:Patent_1 rdf:type tbox:PatentAtEPO . 
abox:Patent_2 rdf:type tbox:PatentAtWIPO . 

and we want to answer a question like:

What’re all the assets under the class Asset?

By using OneOrMorePath (+), all instances instantiated from the Asset concept can be queried using one simple SPARQL query string, i.e.

PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
PREFIX tbox:  <http://www.example.com/tbox#>
SELECT ?asset
WHERE {
  ?asset rdf:type/rdfs:subClassOf+ tbox:Asset .
}

giving results:

asset
<http://www.example.com/abox/Bus_101>
<http://www.example.com/abox/ChemicalPlant_101>
<http://www.example.com/abox/JurongIslandPark>
<http://www.example.com/abox/Flight_101>
<http://www.example.com/abox/IntangibleAsset_101>
<http://www.example.com/abox/FilledPatent_101>
<http://www.example.com/abox/Patent_1>
<http://www.example.com/abox/Patent_2>
<http://www.example.com/abox/Properties_101>
<http://www.example.com/abox/TangibleAsset_101>
<http://www.example.com/abox/TransportVehicle_101>

Object property and subproperty

A similar query can be done to query the hierarchy of object properties, for example, if we have a set of object properties declared as:

PREFIX owl:   <http://www.w3.org/2002/07/owl#>
PREFIX xsd:   <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
PREFIX tbox:  <http://www.example.com/tbox#>
PREFIX abox:  <http://www.example.com/abox/>

# TBox relationship hierarchy
tbox:hasCharacteristic rdf:type rdfs:Property . 

tbox:hasDimension rdfs:subPropertyOf tbox:hasCharacteristic . 
tbox:hasLength rdfs:subPropertyOf tbox:hasDimension . 
tbox:hasLengthInMeters rdfs:subPropertyOf tbox:hasLength . 
tbox:hasLengthInInches rdfs:subPropertyOf tbox:hasLength . 

tbox:hasBrand rdfs:subPropertyOf tbox:hasCharacteristic . 

tbox:hasName rdfs:subPropertyOf tbox:hasCharacteristic . 
tbox:hasFullName rdfs:subPropertyOf tbox:hasName . 
tbox:hasFirstName rdfs:subPropertyOf tbox:hasFullName . 
tbox:hasLastName rdfs:subPropertyOf tbox:hasFullName . 

and again, we are interested to answer questions like:

What’s all the subproperties under the property hasCharacteristic?

A simple query can be used to answer this question:

PREFIX rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
PREFIX tbox:  <http://www.example.com/tbox#>
SELECT ?properties
WHERE {
  ?properties rdfs:subPropertyOf+ tbox:hasCharacteristic .
}

giving results:

properties
<http://www.example.com/tbox#hasBrand>
<http://www.example.com/tbox#hasDimension>
<http://www.example.com/tbox#hasName>
<http://www.example.com/tbox#hasLength>
<http://www.example.com/tbox#hasFullName>
<http://www.example.com/tbox#hasFirstName>
<http://www.example.com/tbox#hasLastName>
<http://www.example.com/tbox#hasLengthInInches>
<http://www.example.com/tbox#hasLengthInMeters>