How to create a small SPARQL query for DBpedia? - sparql

I'm a SPARQL beginner, I would like to know how to create this small query in SPARQL from DBpedia:
The query is: Getting the topics of a thing (name of person, organisation …)
SELECT DISTINCT ?occupation WHERE {
?s <w3.org/2000/01/rdf-schema#label>; 'Madonna'#en . ?occupation dbpedia-owl:occupation ?s
}
So I create this query to get the occupation of Madonna, is this correct? In this case Madonna but it could be anything else.
I tried this query but i think this is wrong:
SELECT DISTINCT ?occupation WHERE {
?s <http://www.w3.org/2000/01/rdf-schema#label> 'Madonna'#en .
?s dbpedia-owl:occupation ?occupation
}
I tried this too i think it's correct:
PREFIX res: <http://dbpedia.org/resource/>
SELECT DISTINCT ?string
WHERE {
res:Tom_Cruise dbpprop:occupation ?string .
}
It works with Tom_Cruise but not with Madonna or barack_Obama for example.

A query like your attempt is a good start:
PREFIX res: <http://dbpedia.org/resource/>
SELECT DISTINCT ?string
WHERE {
res:Tom_Cruise dbpprop:occupation ?string .
}
Now that we've got something specific to work from, we can look at the specific problems that it might have. First, I'm going to rewrite it using the same namespace prefixes that the public endpoint web interface supports, so that we can copy and paste to it. I'm also putting the keywords in lower case because I don't like yelling.
select distinct ?string where {
dbpedia:Tom_Cruise dbpprop:occupation ?string .
}
SPARQL results
Now, you mentioned that
It works with Tom_Cruise but not with Madonna or barack_Obama, for example.
All the data in DBpedia is publicly available for you to browse. If you want to see why there are no results for Madonna, note that dbpedia:Madonna is shorthand for http://dbpedia.org/resource/Madonna and pull up that page in your browser. From the properties listed on that page, you'll see that it's a redirection page (indeed, you'll see the same thing if you go to the corresponding Wikipedia article, http://en.wikipedia.org/wiki/Madonna). You want the IRI http://dbpedia.org/resource/Madonna_(entertainer). Unfortunately, you can't write that directly in a SPARQL query because of the parentheses, so you have to write
select distinct ?string where {
<http://dbpedia.org/resource/Madonna_(entertainer)> dbpprop:occupation ?string .
}
SPARQL results
Now, there are a couple of problems with barack_Obama: (i) the capitalization needs to be Barack_Obama if you want any results. If you visit http://dbpedia.org/resource/Barack_Obama, though, you'll see that there's no dbpprop:occupation property. There's not much you can do about that; you can't query for data that isn't there. The data that is there that might be useful to you (and of a similar nature) would be dbpedia-owl:office, and dbpedia-owl:profession. For instance
select distinct ?string where {
dbpedia:Barack_Obama (dbpedia-owl:office|dbpedia-owl:profession) ?string .
}
SPARQL results

Related

Get movie(s) based on book(s) from DBpedia

I am new to SPARQL and trying to fetch a movie adapted from specific book from dbpedia. This is what I have so far:
PREFIX onto: <http://dbpedia.org/ontology/>
SELECT *
WHERE
{
<http://dbpedia.org/page/2001:_A_Space_Odyssey> a ?type.
?type onto:basedOn ?book .
?book a onto:Book
}
I can't get any results. How can I do that?
When using any web resource, and in your case the property :basedOn, you need to make sure that you have declared the right prefix. If you are querying from the DBpedia SPARQL endpoint, then you can directly use dbo:basedOneven without declaring it, as it is among predefined. Alternatively, if you want to use your own, or if you are using another SPARQL client, make sure that whatever short name you choose for this property, you declare the prefix for http://dbpedia.org/ontology/.
Then, first, to get more result you may not restrict the type of the subject of this triple pattern, as there could be movies that actually not type as such. So, a query like this
select distinct *
{
?movie dbo:basedOn ?book .
?book a dbo:Book .
}
will give you lots of good results but not all. For example, the resource from your example will be missing. You can easily check test the available properties between these two resource with a query like this:
select ?p
{
{<http://dbpedia.org/resource/2001:_A_Space_Odyssey_(film)> ?p <http://dbpedia.org/resource/2001:_A_Space_Odyssey> }
UNION
{ <http://dbpedia.org/resource/2001:_A_Space_Odyssey> ?p <http://dbpedia.org/resource/2001:_A_Space_Odyssey_(film)>}
}
You'll get only one result:
http://www.w3.org/2000/01/rdf-schema#seeAlso
(note that the URI is with 'resource', not with 'page')
Then you may search for any path between the two resource, using the method described here, or find a combination of other patterns that would increase the number of results.

SPARQL query in DBpedia Sorql return no results

I tried to run SPARQL query from the book Learning SPARQL of Bob DuCharme. I runned it on http://dbpedia.org/snorql:
SELECT ?elvisbday WHERE {
<http://dbpedia.org/resource/Elvis_Presley>
<http://dbpedia.org/property/dateOfBirth> ?elvisbday .
}
But the result is an empty output. I checked that URIs are correct. So what's my error? Do I need to add some specific PREFIX?
You got the property wrong. Try this:
SELECT ?elvisbday WHERE {
<http://dbpedia.org/resource/Elvis_Presley>
<http://dbpedia.org/ontology/birthDate> ?elvisbday .
}
In the future, you might want to explore the properties that describe the resource in the endoint if you don't find what you are looking for. You may use this query for that:
SELECT ?p ?o WHERE {
<http://dbpedia.org/resource/Elvis_Presley> ?p ?o
}

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 query for all people for an institution on dbpedia

I'm trying to extract alumni lists for universities using SPARQL.
I've identified the ontologies I need:
http://mappings.dbpedia.org/server/ontology/classes/University
http://mappings.dbpedia.org/server/ontology/classes/Person
I tried this query, which you can examine here:
SELECT * WHERE {
?University dbpedia2:alumni ?Person .
}
Which seemed to make sense, except this returns counts instead of people, as the ontology says the property contains.
I found this query somewhere which seemed to do a better job finding universities, but was very slow.
SELECT * WHERE {
{ <http://dbpedia.org/ontology/University> ?property ?hasValue }
UNION
{ ?isValueOf ?property <http://dbpedia.org/ontology/University> }
}
I also tried going the other way, start with all people and look for their almae matres, in this form:
SELECT * WHERE {
?person dbpedia2:almaMater ?University
}
But this is much slower, possibly because searching through the people space is too laborious. This does actually work, but it returns a different set of results in application---namely, all people with a listed alma mater, rather than all people listed by universities as alumni. I'd prefer a syntax that gets me the alumni.
How can I phrase this to return all alumni listed for universities?
The performance of DBpedia's SPARQL endpoint can be a bit unreliable at times. After all, it's apublic service, and isn't intended for huge queries. Nonetheless, I think you can get what you're looking for here without too much trouble. First, you can check how many results there are with a query like this at the public SPARQL endpoint:
select (count(*) as ?nResults) where {
?person dbpedia-owl:almaMater ?almaMater
}
SPARQL results (64928)
Now, if you just want the big list, you'd get it like this. The order by helps organize the results for easy consumption, but isn't technically necessary:
select ?almaMater ?person where {
?person dbpedia-owl:almaMater ?almaMater
}
order by ?almaMater ?person
SPARQL results
If you need to place some additional restrictions on ?almaMater, e.g., to ensure that it's a university, then you can add them to the query. For instance:
select ?almaMater ?person where {
?person dbpedia-owl:almaMater ?almaMater .
?almaMater a dbpedia-owl:University .
}
order by ?almaMater ?person
SPARQL results
In your last query, you are almost there. However, you are currently asking for any resource that can take the place of the ?University variable. As you only want universities to take that place, you can use another triple to further restrict that variable:
SELECT * WHERE {
?University a dbpedia-owl:University.
?person dbpedia2:almaMater ?University.
}
This means that ?University can only be an individual of class dbpedia-owl:University (where dbpedia-owl is mapped to http://dbpedia.org/ontology/).
Your first query:
SELECT * WHERE {
?University dbpedia2:alumni ?Person .
}
isn't just returning counts; it's returning both counts and individual alumni. Apparently dbpedia's data here is poor quality and there are a number of triples misusing the dbpedia2:alumni relation.
You can filter out the counts by adding a second condition requiring that an entity satisfying Person be a member of the appropriate class:
SELECT * WHERE {
?university dbpedia2:alumni ?person .
?person rdf:type <http://dbpedia.org/ontology/Person>
}
What you see running this is that there are very few individuals tagged as alumni; the data is surprisingly scant, unfortunately.

sparql empty result for dbpedia-owl:influenced property

I am trying to retrieve the value of the dbpedia-owl:influenced in this page e.g: Andy_Warhol
The query I write is:
PREFIX rsc : http://dbpedia.org/resource
PREFIX dbpedia-owl :http://dbpedia.org/ontology
SELECT ?o WHERE {
rsc:Andy_Warhol dbpedia-owl:infuenced ?o .
}
but it is EMPTY.
Strange is that when I have the same query for another property from the ontology type like "birthPlace", the sparql engine gives the result back:
SELECT ?o WHERE {
rsc:Andy_Warhol dbpedia-owl:birthplace ?o .
}
which is a link to another resource:
dbpedia.org/resource/Pittsburgh
I am just confused how to write this query?
besides several formal errors addressed in the answer of #Joshua, there is also the semantic problem that the properties you are looking for - in this case - seem to be found on the entities that were influenced.
this query might give you the desired results
PREFIX rsc: <http://dbpedia.org/resource/>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
SELECT ?s WHERE {
?s dbpedia-owl:influencedBy rsc:Andy_Warhol .
}
run query
There are a few issues here. One is that the SPARQL, as presented, isn't correct. I edited to make the prefix syntax legal, but the prefixes were still wrong (they didn't end with a final slash). You don't want to be querying for http://dbpedia.org/resourceAndy_Warhol after all; you want to query for http://dbpedia.org/resource/Andy_Warhol. Some standard namespaces for DBpedia are listed on their SPARQL endpoint. Using those namespaces and the SPARQL endpoint, we can ask for all the triples that have http://dbpedia.org/resource/Andy_Warhol as the subject with this query:
SELECT * WHERE {
dbpedia:Andy_Warhol ?p ?o .
}
In the results produced there, you'll see the one using http://dbpedia.org/ontology/birthPlace (note the captial P in birthPlace), but you won't see any triples with the predicate http://dbpedia.org/ontology/infuenced, so it makes sense that your first query has no results. Do you have some reason to suppose that there should be some results?