SPARQL: selecting people by country - sparql

I am trying to select all people born in a specific country (e.g. Portugal) from DBPedia.
I could use this query:
SELECT DISTINCT ?person
WHERE {
?person dbpedia-owl:birthPlace dbpedia:Portugal.
}
But the problem is that not all people have dbpedia:Portugal as birthPlace. About 30% of people have just a town name as birthPlace, e.g.
dbpedia:Lisbon
I could add all Portugal cities in a FILTER clause but it's a big list.
May be it's possible to infer Portugal from Lisbon in the SPARQL query somehow?
(to not to add all Portugal cities in FILTER to get ALL persons)

If we assume all the cities in a specific country are defined as part of that country in dbpedia, you could have a query that first looks for the people that have dbpedia:Portugal as a country and then cities within dbpedia:Portugal.
SELECT DISTINCT ?person
WHERE {
?person a dbpedia-owl:Person.
Optional{
?person dbpedia-owl:birthPlace ?country.
}
Optional{
?person dbpedia-owl:birthPlace ?place.
?place dbpedia-owl:country ?country
}
filter(?country= dbpedia:Portugal)
}
The query that you have written identifies 1723 distinct URIs, and this finds 2563 URIs.

Artemis' answer works, but it's very verbose for what's a pretty simple query. It can be simplified to:
select distinct ?person where {
?person a dbpedia-owl:Person ;
dbpedia-owl:birthPlace/dbpedia-owl:country? dbpedia:Portugal
}
SPARQL results (2449)

Full results may be achieved by this http://answers.semanticweb.com/questions/22450/sparql-selecting-people-by-country
- 2730 persons
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX dbpedia: <http://dbpedia.org/resource/>
SELECT ?person
WHERE
{
{?person a <http://dbpedia.org/ontology/Person>;
<http://dbpedia.org/ontology/birthPlace> ?place.
?place <http://dbpedia.org/ontology/country> ?birthCountry.
?birthCountry a <http://dbpedia.org/ontology/Country>.
FILTER (?birthCountry = dbpedia:Portugal).
}
UNION
{ ?person a <http://dbpedia.org/ontology/Person>;
<http://dbpedia.org/ontology/birthPlace> ?birthCountry.
?birthCountry a <http://dbpedia.org/ontology/Country>.
FILTER (?birthCountry = dbpedia:Portugal).
}
}
GROUP BY ?person
ORDER BY ?person

Related

Find all artists who were born in a given city

The following snippet retrieves all artists (names) from around the world using the dbpedia.org database.
prefix dbo: <http://dbpedia.org/ontology/>
select distinct (str(?name_) as ?name) {
?artist a dbo:Artist ;
rdfs:label ?name_ .
}
What I would like to do next, is extend this snippet so that a) I filter by a certain city and b) present the following optional fields:
name (this works already)
city name
birth date
sub class (e.g. Actor, MusicalArtist etc.)
dbo:birthDate will give you the birth date of the artist.
dbo:birthPlace will give you the birth place of the artist.
rdf:type / dbc:subject will give you all the roles that the artist have. Be careful, this one can be tremendous. Perhaps should you refine your research (Yago, dbc, dbo, wikidata, ...).
Here is an example of artists born in Pinner and their birthDate :
prefix dbo: <http://dbpedia.org/ontology/>
select distinct (str(?name_) as ?name) ?birthPlace ?birthDate {
?artist a dbo:Artist ;
rdfs:label ?name_ .
?artist dbo:birthPlace ?birthPlace .
?artist dbo:birthDate ?birthDate .
filter(?birthPlace = dbr:Pinner)
}

SPARQL Query DBpedia Getting Multiple Values

I am new to DBPedia SPARQL Query, I am currently using the http://dbpedia.org/snorql to test queries.
My query looks like this
SELECT ?name ?school ?person
WHERE {
?person dbo:almaMater :Harvard_University .
?person foaf:name ?name .
?person dbo:birthDate ?birth .
?person dbo:country ?country .
?person dbo:almaMater ?school .
FILTER (?birth > "1980-01-01"^^xsd:date) .
} ORDER BY ?name
And below is my result
From the result above, looks like the name "Mingze Xi"#en was repeated thrice. I checked on the link under the person field and it shows that name "Mingze Xi"#en has attended Harvard University, Hangzhou ... and Zhejiang University.
Is there a way for me to query and show that under this name the person has attended these schools? I need this because there is no unique ID that I can use to indicate that this is the same person.

dbpedia fetch entitites in language other than english

I'm trying to extract entity dictionary contains person name etc. from dbpedia using sparql.
PREFIX owl: <http://dbpedia.org/ontology/>
PREFIX dbpprop: <http://dbpedia.org/property/>
SELECT ?name
WHERE {
?person a owl:Person .
?person dbpprop:name ?name . FILTER(lang(?name) = "en")
}
The query above did succeed, but when I change the language name to fr, there is nothing to fetch.
How can I fetch names in other languages?
Moreover, why can't I filter language using query below?
SELECT ?name
WHERE {
?person a owl:Person .
?person dbpprop:language "English"
?person dbpprop:name ?name .
}
// this query returns nothing
I tried to fetch all languages using
SELECT DISTINCT ?lanName
WHERE {
?person a owl:Person .
?person dbpprop:language ?lanName .
}
and the result set contains English.
You need to filter based on the language of the value of the property. Not every property will have values in different languages, but some properties will. It seems, from your example, that dbpprop:name doesn't have values in every language. You may find more values in other languages if you look on the other language specific DBpediae.
However, for something like a name, you'll probably get multi-language results if you use the rdfs:label property. For instance, to get the names of Barack Obama, Daniel Webster, and Johnny Cash in Russian, you could do:
select ?label {
values ?person { dbpedia:Johnny_Cash dbpedia:Barack_Obama dbpedia:Daniel_Webster }
?person rdfs:label ?label .
filter langMatches(lang(?label),"ru")
}
SPARQL results
As an aside, note the use of langMatches rather than equality for matching language tags. This is usually a better approach, because it will correctly handle the different language tags within a language For example (from the SPARQL specification), you can find both of the French literals:
"Cette Série des Années Soixante-dix"#fr .
"Cette Série des Années Septante"#fr-BE .
with langMatches(lang(?title),"fr"), but only the first one with lang(?title) = "fr".
You are looking for rdfs:label for a name, of course all the names are English, you are looking at the English dbpedia.
PREFIX owl: <http://dbpedia.org/ontology/>
PREFIX dbpprop: <http://dbpedia.org/property/>
SELECT distinct *
WHERE {
?person a owl:Person .
?person rdfs:label ?name .
FILTER(lang(?name) = "fr")
}
Again, for the second one, if you replace the name with the rdfs: label you can have:
PREFIX owl: <http://dbpedia.org/ontology/>
PREFIX dbpprop: <http://dbpedia.org/property/>
SELECT distinct *
WHERE {
?person a owl:Person .
?person rdfs:label ?name .
?person dbpprop:language <http://dbpedia.org/resource/English_language>.
}

SPARQL query to retrieve countries population density from DBPedia

Note: This question is different from SPARQL query to retrieve countries population from DBpedia. This question is about population density as understood by DBPedia itself.
How can I retrieve country population density from DBPedia?
I have tried the following, but Virtuoso endpoint returns an empty result set:
PREFIX p: <http://dbpedia.org/property/>
SELECT DISTINCT ?name ?populationDensity
WHERE {
?country a dbpedia-owl:Country .
?country rdfs:label ?name .
?country p:populationDensity ?populationDensity . }
Your current query returns an empty table because there is no ?country that fulfills your query that has the rdf:type dbpedia-owl:Country (represented by 'a'). Check that with this query.
To find the list of rdf:type's that the set of data that does use your populationDensity you could use this query. Following that lead you can just check all properties for Portugal and find that it does have populationDensity, but not the one you used.
This works:
PREFIX dbpedia-ont-PP: <http://dbpedia.org/ontology/PopulatedPlace/>
SELECT DISTINCT ?country ?populationDensity
WHERE {
?country a dbpedia-owl:Country .
?country dbpedia-ont-PP:populationDensity ?populationDensity .
}

GROUP BY in SPARQL?

Assume that I uses the FOAF ontology. I want to return the name and the mbox for each person. I use the following query:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name ?email
WHERE {
?person foaf:name ?name.
?person foaf:mbox ?email.
}
The result of the join is a set of rows: ?person, ?name, ?email. This query is returning the ?name and ?email. Note that in some of the ?person may have multiple mailboxes, so in the returned set, a ?name row may appear multiple times, once for each mailbox.
Is there a solution to make a GROUP BY person ?name?
You can group by person but then you need an aggregation for ?name and ?email
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT (sample(?name) AS ?name2) (sample(?email) as ?email2)
WHERE {
?person foaf:name ?name.
?person foaf:mbox ?email.
} GROUP BY ?person
SAMPLE picks one possible from the group for each ?person.
or maybe
SELECT (group_concat(?name) AS ?names)
(except that's a string).
It may be easier work with
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?email
WHERE {
?person foaf:name ?name.
?person foaf:mbox ?email.
}
ORDER BY ?person ?name ?email
and process the results in your application where you know the incoming results have all the entries for one person is a single section of the results.