How to filter results by city? - sparql

I am using DBpedia to retrieve data on specific towns' POIs, for instance Barcelona. I've tried to find appropriate answers to my problems on Stack Overflow but almost all the answers provided did not work out for me, and given that I am new in SPARQL, I couldn't manage to figure out whether or not it was the syntax that was at fault or if there was something else. I am using the DBpedia SPARQL Endpoint available at the following address : http://dbpedia.org/sparql
I've tried to use some things such as ?citylabel or ?location, and to either use the FILTER command or directly fill a value for these classes. I've also tried a few other things, without satisfying results (and most of the times syntax errors that I could not resolve). These solutions have been, in most cases, applied and seemed to work just fine for people, so I do not understand what's going on.
BASE <http://www.dbpedia.org/resource/>
PREFIX : <http://dbpedia.org/resource/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dbpedia: <http://dbpedia.org/>
PREFIX dbpedia2: <http://dbpedia.org/property/>
PREFIX dbpedia3: <http://dbpedia.org/ontology/>
SELECT (SAMPLE(?label) as ?activity_name)
(SAMPLE(?latitude) as ?activity_lat)
(SAMPLE(?longitude) as ?activity_lon)
(SAMPLE(?homepage) as ?URL)
(SAMPLE(?type) as ?activity_type)
(SAMPLE(?abstract) as ?descriptor)
WHERE
{ ?Museum a dbo:Museum ;
rdfs:label ?label ;
dbo:abstract ?abstract ;
dbo:type ?type ;
geo:lat ?latitude ;
geo:long ?longitude ;
foaf:homepage ?homepage .
}
GROUP BY ?Museum ?label
The results of this query are, I think, pretty much any museum that is known by DBpedia and categorized as such. What I'd like to have is a list of museums within Barcelona. Can somebody give me an rather in-depth answer so I can understand how it is working ? Thanks, in advance.

Related

Case insensitive URI matching in SPARQL

I was hoping someone could help me with a SPARQL query I'm writing. I may get some of the terminology wrong, I'm not a SPARQL expert.
I am trying to get some information from the Nobel prizes SPARQL endpoint (data.nobelprize.org/sparql), retrieving the labels of predicates where the labels of objects match a certain string.
So, for example, if I search for an object with an objectLabel that contains the string 'Robert Burns Woodward', I should receive a number of results including:
predicateLabel, objectLabel
"Laureate","Robert Burns Woodward"
"LaureateAward","Chemistry 1965, Robert Burns Woodward"
"AwardFile","Nobel Lecture Robert Burns Woodward"
I have written the SPARQL below which should work, however it does not retrieve any results:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?predicateLabel ?objectLabel
WHERE
{
?subject ?predicate ?object .
?object rdfs:label ?objectLabel .
?predicate rdfs:label ?predicateLabel .
FILTER contains(?objectLabel, 'Robert Burns Woodward')
}
The reason is that the ?predicate URI is in a different case to the URI which is linked to the corresponding rdfs:label property.
So for example, the predicate
http://data.nobelprize.org/terms/nobelPrize
is used to connect laureates to the prizes they have won. Eg:
sub: http://data.nobelprize.org/resource/laureate/231
pred: http://data.nobelprize.org/terms/nobelPrize
obj: http://data.nobelprize.org/resource/nobelprize/Chemistry/1965
However, the rdfs:label is linked to
http://data.nobelprize.org/terms/NobelPrize
not
http://data.nobelprize.org/terms/nobelPrize
Note the difference in case between the two - the second URI has a lower case 'n' in nobelprize, wheras the first uses an upper case N.
So my question is, is there a way in SPARQL to make a URI case insensitive so that http://data.nobelprize.org/terms/NobelPrize will match with http://data.nobelprize.org/terms/nobelPrize? I know it is possible to search for strings that are case insensitive using FILTER regex or FILTER contains, but I don't know if it is possible with URIs.
You're approaching this the wrong way, I think. That data source has two separate concepts. The resource spelled NobelPrize denotes the class of Nobel Prizes, as can be seen in the ontology. The resource spelled nobelPrize is a different resource, namely the relation between a laureate and a particular Nobel Prize.
In other words: they are distinct, deliberately so, and you shouldn't try to turn them into the same thing by doing case-insensitive matches.
It's somewhat odd that that the nobelPrize property has no label in the SPARQL endpoint, because according to the ontology file it should have one. But given that it doesn't have a label, you're sort of stuck with just getting back the predicate URI itself. You can optionally shorten it by snipping of the namespace part using strafter, like so:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT (strafter(str(?predicate), "http://data.nobelprize.org/terms/") as ?predicateLabel) ?objectLabel
WHERE
{
?subject ?predicate ?object .
?object rdfs:label ?objectLabel .
FILTER contains(?objectLabel, 'Robert Burns Woodward')
}
An alternative, which is somewhat more complex but conceptually neater, is that instead of returning the name of the predicate, you return the name of the type of the object to which the predicate points:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?objectClassName ?objectLabel
WHERE
{
?subject ?predicate ?object .
?object a ?objectClass .
?objectClass rdfs:label ?objectClassName .
?object rdfs:label ?objectLabel .
FILTER contains(?objectLabel, 'Robert Burns Woodward')
}

How to query for publication date of books using SPARQL in DBPEDIA

I am trying to retrieve the publication date and the no.of pages for books in DBpedia. I tried the following query and it gives empty results. I see that these are properties under book(http://mappings.dbpedia.org/server/ontology/classes/Book) but could not retrieve it.
I would like to know if there is an error in the code or if dbpedia does not store these dates related to books.
SELECT ?book ?genre ?date ?numberOfPages
WHERE {
?book rdf:type dbpedia-owl:Book .
?book dbp:genre ?genre .
?book dbp:firstPublicationDate ?date .
OPTIONAL {?book dbp:numberOfPages ?numberOfPages .}
}
The dbp:firstPublicationDate does not work for two reasons:
First, as pointed in the first answer, you used the wrong prefix.
But even if you correct it, you'll see that you would still have no results. Then the best thing to do is to test with the minimum number of patters, in you case you should as for books with first publication date, two triple pattern only. If you still don't get results, you should test how <http://dbpedia.org/ontology/firstPublicationDate> is actually used with a query like this:
SELECT ?class (COUNT (DISTINCT ?s) AS ?instances)
WHERE {
?s <http://dbpedia.org/ontology/firstPublicationDate> ?date ;
a ?class
}
GROUP BY ?class
ORDER BY DESC(?instances)
LIMIT 1000
Mapping based properties are using the namespace http://dbpedia.org/ontology/, thus, the prefix must be dbo instead of dbp, which stands for http://dbpedia.org/property/.
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
SELECT ?book ?genre ?date ?numberOfPages
WHERE {
?book a dbo:Book ;
dbp:genre ?genre ;
dbo:firstPublicationDate ?date .
OPTIONAL {?book dbp:numberOfPages ?numberOfPages .}
}
Some additional comments:
put the prefixes to the SPARQL query such that others here can run it without any exceptions (also in the future) - the current SPARQL query uses dbpedia-owl but this one is not pre-defined on the official DBpedia anymore - it's called dbo instead
which brings me to the second point -> if you're using a public SPARQL endpoint, show its URL
you can start debugging your own SPARQL query by simply starting with only parts of it and adding more triple patterns then, e.g. in your case you could check if there is any triple with the property with
PREFIX dbp: <http://dbpedia.org/property/>
SELECT * WHERE {?book dbp:firstPublicationDate ?date } LIMIT 10
Update
As Ivo Velitchkov noticed in his answer below, the property dbo:firstPublicationDate is only used for mangas, etc., i.e. written work that was published periodically. Thus, the result will be empty.

Sparql: getting all politicians who ruled a city

I'm new to sparql and I'm trying to understand how to get the resources I need for building a query. I started trying to get all the politicians that ruled a city or a country, and at the moment I could do just the following:
I started by following the links in snorql (in the prefixes) and looking for an entity by adding "politician" at the end. I found one :
PREFIX : <http://dbpedia.org/resource/>
So I wrote http://dbpedia.org/resource/Politician and the resource does exist. I tryed to use it in this way:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbpedia: <http://dbpedia.org/resource/>
SELECT ?thing WHERE {
?thing a :Politician .
?thing dbo:birthPlace dbpedia:Italy.
}
LIMIT 50
Run in virtuoso.
Even if I remove the second line of the SELECT, I have no results. But if I change the first line with: ?thing a dbo:Person. or even if I remove it, I get the people born in Italy. But not just the politicians. A second problem is I don't need the politicians that were born but ruled that place. How or where can I find that kind of "relations/descriptors"? Now I am just googling and copy-pasting some existing examples, but I would like to understand how to look for more specific things.
Thanks in advance
Your first query isn't working because Politician is not part of the default (:) namespace, but instead it is present in DBpedia Ontology namespace (dbo).
So, your query should be:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbpedia: <http://dbpedia.org/resource/>
SELECT ?thing WHERE {
?thing a dbo:Politician .
?thing dbo:birthPlace dbpedia:Italy.
}
LIMIT 50
To list all politician who ruled Italy you would need to know which is the predicate for "ruled". Once you have it you can construct a query.
To list all predicates present in the database you can write something like this
SELECT DISTINCT(?b) WHERE {
?a ?b ?c.
}
And it will list all predicates.
I would recommend you to browse through one or two politician and see the predicates they have to check if one works for you.

Fundamental understanding of SPARQL

I try to understand SPARQL and mess around with the SPARQL Tool that is provided by dbpedia. I've read the w3 documentation and now I want to create my very own query. I would like to find the names of all books in dbpedia written by J. J. R. Tolkien.
Therefore I "designed" this query:
SELECT ?name WHERE { ?name ?author "J._R._R._Tolkien".
?name ?mediaType "Print"}
The result is empty, but I would at least expect this book popping up:
http://dbpedia.org/page/The_Lord_of_the_Rings
Can someone tell me, what my conceptual mistake is?
I good approach would be to review his DBpedia page and then choose the desired properties. In your case two good candidates are notableWork and author. Here's a query with both of them, effectively using the latter.
PREFIX : <http://dbpedia.org/resource/>
PREFIX o: <http://dbpedia.org/ontology/>
PREFIX p: <http://dbpedia.org/property/>
SELECT DISTINCT ?is_author_of #?has_notable_work
FROM <http://dbpedia.org/>
WHERE {
:J._R._R._Tolkien rdf:type o:Writer ;
#o:notableWork ?has_notable_work ;
^p:author ?is_author_of .
}
I have used rdf:type o:Writer to reduce possible ambiguity (none, in case of using URI of an individual resource in dbpedia), and ^ to get the right direction. My preference for ?is_author_of and ?has_notable_workinstead of e.g. ?book and ?popular_book was because I'm not sure what kind of work is he author of.

SPARQL query returns no data

Why does this SPARQL query return no data?
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX dbpedia: <http://dbpedia.org/resource/>
SELECT *
WHERE {
<http://dbpedia.org/resource/Louis,_Prince_of_Condé_(1530–1569)> dbpedia-owl:abstract ?abstract
}
LIMIT 1
If you look at the DBpedia page, it shows the person has an abstract. Is it to do with the brackets in the URL? If so, how can I get round this?
This URI does not lead to the same result as the DBpedia page - for what ever reason. You can see this with
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX dbpedia: <http://dbpedia.org/resource/>
SELECT *
WHERE {
<http://dbpedia.org/resource/Louis,_Prince_of_Condé_(1530–1569)> ?p ?o
}
LIMIT 100
But it has an owl:sameAs relation to
http://dbpedia.org/resource/Louis,_Prince_of_Cond%C3%A9_(1530%E2%80%931569)
That means if you use this URI in your query, it should work as expected. But you should indeed apply a FILTER on the language, e.g. 'en' for English abstracts.
As AKSW mentions, the resource actually doesn't have many properties, but is connected to the "canonical" version by an owl:sameAs link. You can keep using the IRI that you're using now, follow owl:sameAs in either direction to any of its equal resources (let's call them ?s), and then ask for the abstract of ?s. (And then it's not a bad idea to filter by language, if that's applicable.) You can do this with a query like this (note that the current DBpedia endpoint uses dbo:, now, not the older dbpedia-owl:):
select ?abstract where {
<http://dbpedia.org/resource/Louis,_Prince_of_Condé_(1530–1569)> (owl:sameAs|^owl:sameAs)* ?s .
?s dbo:abstract ?abstract .
filter langMatches(lang(?abstract),'en')
}
It does not have dbpedia-owl:abstract predicate. If you list its predicates you find the following properties:
http://www.w3.org/2002/07/owl#sameAs
http://xmlns.com/foaf/0.1/name
http://purl.org/dc/elements/1.1/description
http://dbpedia.org/ontology/alias
http://dbpedia.org/ontology/birthYear
http://dbpedia.org/ontology/deathYear
http://dbpedia.org/ontology/viafId
http://dbpedia.org/ontology/deathPlace
http://dbpedia.org/ontology/deathDate
http://dbpedia.org/ontology/birthPlace
http://dbpedia.org/ontology/birthDate