Query SPARQL resulting level 1 hierarchy - sparql

So, the case is i have an ontology, which contains subclasses and no individual like the picture below.
I want to do a query with SPARQL which will result in level 1 in the hierarchy (subclass of Thing). is that possible to do it?

To allow the questioner to actually select an answer, this from #UninformedUser's comments:
SELECT ?cls
WHERE {
?cls a owl:Class .
FILTER NOT EXISTS {
?cls rdfs:subClassOf ?sup .
FILTER(?sup != owl:Thing)
}
}
"this works if all classes are "tagged" as owl:Class"

I think you're saying "find all the things that are subclasses of owl:Thing and only subclasses of owl:Thing so why not look for all things rdfs:subClassOf other things and remove all the non owl:Thing matches:
SELECT *
WHERE {
?x rds:subClassOf ?y .
FILTER (!sameTerm(?y, owl:Thing))
}

Related

Wikidata - get the full subhierachy of one class as well as all nodes

I need the complete hierarchy that is under Food Q2095.
All levels of subclasses should also be included. Additionally all entities that are attached to a (sub)class.
How can I query this?
SELECT ?node WHERE {?node ?pred wd:Q2095}
Direct query at wikidata
Thank you.
Try this:
SELECT ?subclass ?entity ?predicate
WHERE{
?subclass wdt:P279* wd:Q2095
{?entity ?predicate ?subclass }
UNION
{?subclass ?predicate ?entity }
}
The first part of the body of the query makes sure your subclass eventually leads to food.
The second looks for entities that are attached to the subclass, i.e. are either the object or the subject of a triple containing the said subclass.
Depending on whether you want to restrict the scope of the predicate. (i.e. avoid rdfs:label and others), you can use something like this too:
?predicate a owl:ObjectProperty .
under the first line of the body of the query.
#UninformedUser's comment shows you how to get the level of the subclass.

Multiple SELECT query for getting all children of a given root

I want to define the root categories corresponding to interests of users. Then I need to return all other potential interests under given root directory.
I tried the following query, but it looks like it enters into a loop (the query is executing internally).
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.myweb.com/myontology.owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?user ?othercat
WHERE
{
?othercat rdfs:subClassOf ?root .
{
SELECT ?user ?retailcat ?root
WHERE {
?user rdf:type owl:User .
?user owl:hasUserProfile ?userprofile .
?userprofile rdf:type owl:UserProfile .
?userprofile owl:interestedIn ?retailcat .
?entity rdf:type ?type .
?type rdfs:subClassOf* ?retailcat .
?retailcat rdfs:subClassOf ?root .
}
}
}
Indeed when I execute the sub-query, it works fine, but it returns current interests of a user, without providing the information of other child-concepts of the same root.
How to solve this issue?
I tried the following query, but it looks like it enters into a loop (the query is executing internally).
There shouldn't be a way for a SPARQL query to enter into a loop. Subqueries are executed first, and then the enclosing query is executed. There's no way to re-execute the inner part or anything like that. (Of course, a query could be expensive and take a long time, but that's not a loop, and is still bounded, in principle.)
As an aside, using owl: as prefix for something other than the standard OWL namespace is somewhat confusing, and likely to mislead other developers when they see your query. There's nothing incorrect about it per se, but you might want to consider using a different prefix for your namespace.
You do have one part of your query that could make things rather expensive. You have the pattern
?entity rdf:type ?type .
?type rdfs:subClassOf* ?retailcat .
where ?entity isn't connected to anything else, and isn't used anywhere else. That means that you'll have a subquery solution for every possible value of ?entity, and that just means you're multiplying the number of results by the number of possible values of ?entity.
If I understand your query, you're trying to go from a user's categories of interest, up the category tree to some root concepts and then find other categories under that root. You don't actually need a subquery for that; you can do it with a non-nested query:
select ?user ?othercat {
?user rdf:type owl:User .
?user owl:hasUserProfile ?userprofile .
?userprofile rdf:type owl:UserProfile .
?userprofile owl:interestedIn ?retailcat .
?retailcat rdfs:subClassOf ?root .
?othercat rdfs:subClassOf ?root .
}
That will find values of ?othercat that are siblings of ?retailcat, along with ?retailcat itself. If you want to avoid ?retailcat, you can add
filter(?othercat != ?retailcat)
but that shouldn't really impact performance much; that's just one result to filter out.
The only other factor that you might want to consider is that you're not really finding a "root" of the category tree with rdfs:subClassOf; you're just going up one level. E.g., if your category tree looks like
Automobile
SUV
SportsCar
Corvette
Mustang
and a user is interested in Mustang, then you'll go up to SportsCar and find Corvette, but you won't be going any farther up the tree. (If you have inference available, you may actually go farther up the tree, but I'm assuming for the moment that you don't.) To follow the subclass links up the tree, you can add * to the path to follow the chain:
?retailcat rdfs:subClassOf* ?root .
?othercat rdfs:subClassOf ?root .
Then you'd get all the classes in the tree (except the very top level one, Automobile).

How to retrieve abstract for a DBpedia resource?

I need to find all DBpedia categories and articles that their abstract include a specific word.
I know how to write a SPARQL query that queries the label like the following:
SELECT ?uri ?txt WHERE {
?uri rdfs:label ?txt .
?txt bif:contains "Machine" .
}
but I have not figured out yet how to search the abstract.
I've tried with the following but it seems not to be correct.
SELECT ?uri ?txt WHERE {
?uri owl:abstract ?txt .
?txt bif:contains "Machine" .
}
How can I retrieve the abstract in order to query its text?
Since you already know how to search a string for text content, this question is really about how to get the abstract. If you retrieve any DBpedia resource in a web browser, e.g., http://dbpedia.org/resource/Mount_Monadnock (which will redirect to http://dbpedia.org/page/Mount_Monadnock), you can see the triples of which it's a subject or predicate. In this case, you'll see that the property is dbpedia-owl:abstract. Thus you can do things like
select * where {
?s dbpedia-owl:abstract ?abstract .
?abstract bif:contains "Monadnock" .
filter langMatches(lang(?abstract),"en")
}
limit 10
SPARQL results
Instead of visiting the page for the resource, which not endpoints will support, you could have simply retrieved all the triples for the subject, and looked at which ones relate it to its abstract. Since you know the abstract is a literal, you could even restrict it to triples where the object is a literal, and perhaps with a language that you want. E.g.,
select ?p ?o where {
dbpedia:Mount_Monadnock ?p ?o .
filter ( isLiteral(?o) && langMatches(lang(?o),'en') )
}
SPARQL results
This also clearly shows that the property you want is http://dbpedia.org/ontology/abstract. When you have a live query interface that you can use to pull down arbitrary data, it's very easy to find out what parts of the data you want. Just pull down more than you want at first, and then refine to get just what you want.

Sparql to recover the Type of a DBpedia resource

I need a Sparql query to recover the Type of a specific DBpedia resource. Eg.:
pt.DBpedia resource: http://pt.dbpedia.org/resource/Argentina
Expected type: Country (as can be seen at http://pt.dbpedia.org/page/Argentina)
Using pt.DBpedia Sparql Virtuoso Interface (http://pt.dbpedia.org/sparql) I have the query below:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?l ?t where {
?l rdfs:label "Argentina"#pt .
?l rdf:type ?t .
}
But it is not recovering anything, just print the variable names. The virtuoso answer.
Actually I do not need to recover the label (?l) too.
Anyone can fix it, or help me to define the correct query?
http in graph name
I'm not sure how you generated your query string, but when I copy and paste your query into the endpoint and run it, I get results, and the resulting URL looks like:
http://pt.dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fpt.dbpedia.org&sho...
However, the link in your question is:
http://pt.dbpedia.org/sparql?default-graph-uri=pt.dbpedia.org%2F&should-sponge...
If you look carefully, you'll see that the default-graph-uri parameters are different:
yours: pt.dbpedia.org%2F
mine: http%3A%2F%2Fpt.dbpedia.org
I'm not sure how you got a URL like the one you did, but it's not right; the default-graph-uri needs to be http://pt.dbpedia.org, not pt.dbpedia.org/.
The query is fine
When I run the query you've provided at the endpoint you've linked to, I get the results that I'd expect. It's worth noting that the label here is the literal "Argentina"#pt, and that what you've called ?l is the individual, not the label. The individual ?l has the label "Argentina"#pt.
We can simplify your query a bit, using ?i instead of ?l (to suggest individual):
select ?i ?type where {
?i rdfs:label "Argentina"#pt ;
a ?type .
}
When I run this at the Portuguese endpoint, I get these results:
If you don't want the individual in the results, you don't have to select it:
select ?type where {
?i rdfs:label "Argentina"#pt ;
a ?type .
}
or even:
select ?type where {
[ rdfs:label "Argentina"#pt ; a ?type ]
}
If you know the identifier of the resource, and don't need to retrieve it by using its label, you can even just do:
select ?type where {
dbpedia-pt:Argentina a ?type
}
type
==========================================
http://www.w3.org/2002/07/owl#Thing
http://www.opengis.net/gml/_Feature
http://dbpedia.org/ontology/Place
http://dbpedia.org/ontology/PopulatedPlace
http://dbpedia.org/ontology/Country
http://schema.org/Place
http://schema.org/Country

Get all properties for a DBpedia class

How to get a list of properties for a specific class? Consider the class dbpedia-owl:Person. All instances of the Person class have some properties prefixed with dbpprop:. How can I get all the dbpprop: properties that we may find for all the instance of the Person class?
The one that works is:
select distinct ?property where {
?property <http://www.w3.org/2000/01/rdf-schema#domain>
<http://dbpedia.org/ontology/Person> . }
In this query you are asking for all the properties that have dbpedia:Person as rdfs:domain. This query requires a schema definition to work and sometime datasets don't really follow perfectly the schemas. For those datasets you would try this other query
select distinct ?property where {
?instance a <http://dbpedia.org/ontology/Person> .
?instance ?property ?obj . }
This query looks at every instance of person binding every property that comes out of it. It is much harder than the first one, and in the dbpedia public instance you will get a time out. So you are better off with the first one if you want to use the public endpoint.
To get all transitive properties you can ask this query
select distinct ?property where{
{
?property rdfs:domain ?class .
dbpedia-owl:Person rdfs:subClassOf+ ?class.
} UNION {
?property rdfs:domain dbpedia-owl:Person.
}}
The '+' in the 'rdfs:subClassOf' is a property path expression [1] that fetches all uperclasses of Person as well.
These properties are also valid for Person.
Also note that the dbprop namespace is not recommended because the data is raw and not normalized to a datatype.
[1] http://www.w3.org/TR/2010/WD-sparql11-property-paths-20100126/
Disclosure: I am a DBpedia developer