I have the following SPARQL Query:
SELECT ?depthClass (count(?mid)-1 as ?depth)
WHERE {
{
SELECT ?root WHERE {
?root a owl:Class
FILTER NOT EXISTS {
?root rdfs:subClassOf ?superroot
filter ( ?root != ?superroot )
}
}
}
?depthClass rdfs:subClassOf* ?mid .
?mid rdfs:subClassOf* ?root .
}
group by ?depthClass
order by ?depth
It is supposed to return the class and the depth of the given class depthClass. However, it does not return anything. I don't see any error in the query.
After debugging I noticed that, since I was using owlready2 rdflib implementation, it probably did not support ?root a owl:Class syntax, after changing it to ?root rdf:type owl:Class it started working!
Related
I know there's some answers from Query SPARQL resulting level 1 hierarchy and SPARQL Query - get top-level classes of a dataset
But this isn't enough for what I'm trying to do. I have the class Category, subclass of owl:Thing, and the query
SELECT DISTINCT ?cls
WHERE {
?cls a owl:Class .
FILTER NOT EXISTS {
?cls rdfs:subClassOf ?sup .
FILTER(?sup != owl:Thing)
}
}
works fine for other classes without restrictions but it doesn't return Category because Category has restrictions, which this query sees them as separate classes. My Category class looks like this:
:Category rdf:type owl:Class ;
rdfs:subClassOf owl:Thing ,
[ rdf:type owl:Restriction ;
owl:onProperty :hasConfidence ;
owl:minCardinality "0"^^xsd:nonNegativeInteger
] ,
[ rdf:type owl:Restriction ;
owl:onProperty :hasIntensity ;
owl:minCardinality "0"^^xsd:nonNegativeInteger
] ,
[ rdf:type owl:Restriction ;
owl:onProperty :hasConfidence ;
owl:maxCardinality "1"^^xsd:nonNegativeInteger
] ,
[ rdf:type owl:Restriction ;
owl:onProperty :hasIntensity ;
owl:maxCardinality "1"^^xsd:nonNegativeInteger
] ;
rdfs:comment """Category refers to the classification used to annotate the emotion.
This can be further expanded to add support to new categories."""#en ;
rdfs:label "Category"#en .
How can I modify the query to add these top-level classes that are "subclasses" of some restrictions? I need a FILTER for those restrictions but I don't know how to go into this. I tried doing
SELECT DISTINCT ?cls
WHERE
{
{
?cls a owl:Class .
FILTER NOT EXISTS {
?cls rdfs:subClassOf ?sup .
FILTER(?sup != owl:Thing)
}
}
UNION
{ ?cls rdfs:subClassOf owl:Thing }
}
and it works but that implies that Category has to be EXPLICITLY subclass of owl:Thing, which isn't always the case in a lot of ontologies.
I figured it out. Here's the query for anyone who's having trouble with this like me:
SELECT DISTINCT ?cls
WHERE
{
?cls a owl:Class .
FILTER NOT EXISTS {
?cls rdfs:subClassOf ?sup .
FILTER(?sup != owl:Thing) .
FILTER NOT EXISTS {
?sup a owl:Restriction .
}
}
FILTER(?cls != owl:Thing) # We get rid of the root class from the query results
}
Basically, all I needed was a filter for the owl:Restriction class types. I also added a filter to get rid of owl:Thing from the query results. With this query I'm able to get the Category class from my ontology, which is part of the top-layer / level 1 hierarchy.
The following query works as expected:
PREFIX nct: <http://n2t.net/ark:/39333/ncg/type#>
PREFIX ncv: <http://n2t.net/ark:/39333/ncg/vocab#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT ?label ?url WHERE {
BIND("Chapel Hill" as ?placename)
{
?marker
a nct:HistoricalMarker ;
skos:prefLabel ?label ;
skos:note ?markerDescription ;
.
FILTER CONTAINS(?markerDescription, "Chapel Hill")
}
UNION
{
?musician skos:prefLabel ?label .
?place
skos:prefLabel ?placename ;
ncv:associatedWithAgent ?musician ;
.
}
UNION
{
?movie skos:prefLabel ?label .
?place
skos:prefLabel ?placename ;
ncv:filmingLocationFor ?movie ;
.
}
}
But if I change FILTER CONTAINS(?markerDescription, "Chapel Hill") in the first block to FILTER CONTAINS(?markerDescription, ?placename), it no longer works.
Try the working query.
Try the not working query.
Why?
I am trying to list root classes of the NIF ontology which is an ontology created of several other ontologies as its modules.
I use this code from an online resource:
SELECT ?directSub ?super
WHERE { ?directSub rdfs:subClassOf ?super .
FILTER NOT EXISTS {
?directSub rdfs:subClassOf ?otherSub .
FILTER (?otherSub != ?directSub)
}
}
The logic of the code seems fine but it does not return any answers (even when I test it on other ontologies)! Why is that?
The #UninformedUser's answer works fine. However, there is an exception that does not work with that solution, which is a root class without any child. The solution assumes that all roots have subclasses, which is not always true.
The following piece of code can find these classes:
SELECT DISTINCT ?exClass
WHERE {
?exClass rdf:type owl:Class
FILTER NOT EXISTS { ?subClass rdfs:subClassOf ?exClass }
FILTER NOT EXISTS { ?exClass rdfs:subClassOf ?supClass }}
Hence, the full SPARQL query for finding all root nodes is:
SELECT DISTINCT ?rootClass
WHERE {{
?rootClass rdf:type owl:Class .
?subClass rdf:type owl:Class .
?subClass rdfs:subClassOf ?rootClass
FILTER NOT EXISTS {
?rootClass rdfs:subClassOf ?otherSup
FILTER (?otherSup != owl:Thing)}
} UNION {
?rootClass rdf:type owl:Class
FILTER NOT EXISTS { ?subClass rdfs:subClassOf ?rootClass }
FILTER NOT EXISTS { ?rootClass rdfs:subClassOf ?supClass }}}
I am sure that the above pieces of code can be improved, however, I am just a beginner. I really would appreciate it if someone can provide tips on how to improve it.
I am trying to get the hierarchy of super and subclass of dbpedia ontolgy.
Sparql query:
SELECT DISTINCT ?superclass ?subclass
WHERE
{
?subclass a owl:Class .
?subclass rdfs:subClassOf ?superclass
}
ORDER BY ?superclass ?subclass
It gives me all classes. But when I am trying to get the counts of entity inside classes. Some classes have entity while some don't have.
Sparql query to get the count of entity inside classes.
Getting Entities:
SELECT DISTINCT ?label AS ?label
?name AS ?name
?link AS ?link
WHERE
{
?link rdf:type <http://www.wikidata.org/entity/Q12136> .
OPTIONAL { ?link foaf:name ?name }
OPTIONAL { ?link rdfs:label ?label }
FILTER( lang(?label) = "en" )
}
Not getting Entities:
SELECT DISTINCT ?label AS ?label
?name AS ?name
?link AS ?link
WHERE
{
?link rdf:type <http://www.wikidata.org/entity/Q18553493> .
OPTIONAL { ?link foaf:name ?name }
OPTIONAL { ?link rdfs:label ?label }
FILTER(lang(?label) = "en" )
}
Why some classes don't have entities? Or Am I doing something wrong? Any help please?
First of all, you are talking about classes and not ontologies. I don't know why you think that entities are instances of ontologies, especially when you're talking about individuals/instances/resources.
Second, why shouldn't there be classes that do not have instances yet?
Hi Guys am trying run a SPARQL query on Virtuoso version 6.1.x. Here is the query:
SPARQL PREFIX fns: <NAMESPACE> SELECT ?birth ?death ?age ?value ?typeId FROM <http://freebaseInc5>
WHERE { fns:m.030pk7c fns:people.person.date_of_birth ?birth; fns:people.deceased_person.date_of_death ?death; BIND(year(?death)-year(?birth) as ?age ) .
OPTIONAL {?mid fns:common.topic.notable_types ?type . ?type fns:type.object.id ?typeId } .
OPTIONAL {?mid fns:type.object.name ?value FILTER langMatches(lang(?value), "en") }}
I am getting the error complaining about the syntax:
> SQLState: 37000
Message: SQ074: Line 4: SP030: SPARQL compiler, line 2: syntax error at 'BIND' before '('
SPARQL PREFIX fns: <NAMESPACE> SELECT ?birth ?death ?age ?value ?typeId FROM <NAMESPACE>
WHERE { fns:m.030pk7c fns:people.person.date_of_birth ?birth; fns:people.deceased_person.date_of_death ?death; BIND(year(?death)-year(?birth) as ?age ) .
OPTIONAL {?mid fns:common.topic.notable_types ?type . ?type fns:type.object.id ?typeId } .
OPTIONAL {?mid fns:type.object.name ?value FILTER langMatches(lang(?value), "en") }}
I don't see what the error is; what am I missing?
It's actually legal SPARQL…
Here's your query, with improved formatting, and with the "SPARQL" removed from the beginning, but no other changes:
PREFIX fns: <NAMESPACE>
SELECT ?birth ?death ?age ?value ?typeId
FROM <http://freebaseInc5>
WHERE {
fns:m.030pk7c fns:people.person.date_of_birth ?birth ;
fns:people.deceased_person.date_of_death ?death ;
BIND(year(?death)-year(?birth) as ?age ) .
OPTIONAL {
?mid fns:common.topic.notable_types ?type .
?type fns:type.object.id ?typeId
} .
OPTIONAL {
?mid fns:type.object.name ?value
FILTER langMatches(lang(?value), "en")
}
}
According to sparql.org's query validator, the query is well formed (which actually suprised me, given the ; after ?death, but I guess it's OK after all).
…but Virtuoso doesn't like it.
But if I try to run this on DBpedia's endpoint, which runs Virtuoso, (along with a limit 1, just to make sure it's not actually going to use much in the way of resources), I see the error you're talking about:
Virtuoso 37000 Error SP030: SPARQL compiler, line 10: syntax error at 'BIND' before '('
SPARQL query:
define sql:big-data-const 0
#output-format:text/html
define sql:signal-void-variables 1 define input:default-graph-uri <http://dbpedia.org> PREFIX fns: <NAMESPACE>
SELECT ?birth ?death ?age ?value ?typeId
FROM <http://freebaseInc5>
WHERE {
fns:m.030pk7c fns:people.person.date_of_birth ?birth ;
fns:people.deceased_person.date_of_death ?death ;
BIND(year(?death)-year(?birth) as ?age ) .
OPTIONAL {
?mid fns:common.topic.notable_types ?type .
?type fns:type.object.id ?typeId
} .
OPTIONAL {
?mid fns:type.object.name ?value
FILTER langMatches(lang(?value), "en")
}
}
LIMIT 1
However, if you change the ; after ?death to ., or remove it completely, the query is accepted without any problem.