Reputation: 769
Please help me with the SPARQL query.
I have an ontology with the class 'Building' as a subclass of owl:Thing
. 'Building' has it's own sub classes like: Church, Medical, Shop.
Each of these sub classes has it's own labels ( seeAlso
). For instance: Shop has labels like supermarket, bakery, market etc. Church has labels like Chapel, Cathedral etc.
The Individuals look like this:
I need to do a SPARQL query, which will retrieve the individuals according to the labels.
So let's say I want to get all the individuals of that subclass which has the labels of type seeAlso
"bakery". In this case I expect to get bakery1 and supermarket1
I have tried this, but it seems like this query is wrong:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?individual ?class ?label
WHERE {
?individual rdf:type owl:NamedIndividual .
?class rdf:type owl:Class .
FILTER(?label="bakery")
}
If I delete the line with FILTER
, I will get only the individuals and classes, but not related to each other as they should. Protege just returns me all the possible connections Class - Individual
Upvotes: 2
Views: 9682
Reputation: 4001
Given comments to the answer, the intent is to build synonyms, not separate instances. There are a few ways to do this, but SKOS is specifically designed for such vocabulary relationships. The property skos:prefLabel
is used for the display label, and synonyms can be defined by skos:altLabel
. The hierarchy you have can be retained, just use skos:altLabel
instead of 'rdf:seeAlso' (which is normally used for reference links ourtide of the ontology).
So the data, in a Turtle text serialization would look like:
:Shop rdfs:subClassOf :Building .
:Shop skos:prefLabel "Shop"^^xsd:string .
:Shop skos:altLabel "supermarket"^^xsd:string .
:Shop skos:altLabel "bakery"^^xsd:string .
:Shop skos:altLabel "market"^^xsd:string .
For the query, the OP says to match by the string - the preflabel
in this case:
SELECT ?individual ?label
WHERE {
?individual skos:prefLabel "Shop"^^xsd:string .
?individual skos:altLabel ?label
}
Upvotes: 3
Reputation: 4001
I think what you are looking for is all of the instances of the class :Building
and its subclasses. Also note that if ?label
is not bound, the filter will always fail. So you'll need to do the following:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>SELECT
WHERE {
?cls rdfs:subClassOf* :Building .
?individual a ?cls .
?individual rdfs:seeAlso ?label .
FILTER (?label = "bakery")
}
…and that is a classic anti-pattern for SPARQL. As much as possible, you should use basic graph patterns, so this is a more correct query:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>SELECT
WHERE {
?cls rdfs:subClassOf* :Building .
?individual a ?cls .
?individual rdfs:seeAlso "bakery" .
}
Note the third triple pattern uses the literal in the triple pattern. Also, I don't think the model you have should be using rdfs:seeAlso
for the label of the instance. Instead I'd suggest a separate instance for each kind Shop, etc. and use rdfs:label
to represent the label of the instance.
Lastly, if you need to do an inexact match you can use regex
. For example to find "bakery" regardless of case, use the following:
#-- …
?individual rdfs:seeAlso ?label .
FILTER regex(?label, "Bakery", "i")
Upvotes: 3