I am trying to complete the following case in SPARQL. I want to return the labels of the deathPlace for the Greek writer "Nikos Kazantzakis"
The workspace to copy-paste the queries below.
I am running the following query:
PREFIX dp: <https://dbpedia.org/page/West_Germany>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT (?musician as ?musicianName) ?nationality ?deathTime ?deathPlaceLabel ?abstarct
WHERE
{
?musician rdfs:label "Nikos Kazantzakis" @en .
?musician dbo:nationality ?nationality .
?musician dbo:deathDate ?deathTime .
?musician dbo:deathPlace ?deathPlaceLabel .
#dp:commonName ?deathPlaceLabel?deathPlaceLabel .
?musician dbo:abstract ?abstarct .
FILTER (lang(?abstarct) = 'en')
}
This has the following result:
The ?deathPlaceLabel value is printed but as the hyperlink resource. Is it feasible to enter each property (i.e. dbr:West_Germany, dbr:Germany, dbr:Freiburg) and print their labels?
What I tried is to pass the West_Germnay resource to a prefix and then call the "commonName" property from that prefix. Likewise,
PREFIX dp: <https://dbpedia.org/page/West_Germany>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT (?musician as ?musicianName) ?nationality ?deathTime ?deathPlaceLabel ?abstarct
WHERE
{
?musician rdfs:label "Nikos Kazantzakis" @en .
?musician dbo:nationality ?nationality .
?musician dbo:deathDate ?deathTime .
#?musician dbo:deathPlace ?deathPlaceLabel .
?dplabel dp:commonName ?deathPlaceLabel .
?musician dbo:abstract ?abstarct .
FILTER (lang(?abstarct) = 'en')
}
But I seem to retrieve an empty column(s) result.
To get the rdfs:label
of the entities, you could use:
?musician dbo:deathPlace ?deathPlace .
?deathPlace rdfs:label ?deathPlaceLabel .
If you don’t need to do anything else with ?deathPlace
, you can use a property path instead:
?musician dbo:deathPlace/rdfs:label ?deathPlaceLabel .
Full query:
PREFIX dbr: <http://dbpedia.org/resource/>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?musician ?nationality ?deathDate ?deathPlaceLabel ?abstract
WHERE
{
VALUES ?musician { dbr:Nikos_Kazantzakis }
?musician dbo:nationality ?nationality ;
dbo:deathDate ?deathDate ;
dbo:deathPlace/rdfs:label ?deathPlaceLabel ;
dbo:abstract ?abstract .
FILTER(lang(?abstract) = 'en') .
FILTER(lang(?deathPlaceLabel) = 'en') .
}
If you already know which entity you want to query, it’s better to use its URI instead of its label (it’s faster that way, and you make sure that you get exactly the entity you want, as there could be different entities with the same label).
So I replaced rdfs:label "Nikos Kazantzakis"@en
with a VALUES
block, in which you can add/remove the URIs of musicians.
Note that it’s important to use the URIs with /resource/
(which represents the musician) instead of /page/
(which represents the page about the musician).
In case you only want one result line, you could use GROUP_CONCAT
for ?deathPlaceLabel
:
PREFIX dbr: <http://dbpedia.org/resource/>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?musician ?nationality ?deathDate (GROUP_CONCAT(?deathPlaceLabel; separator=", ") AS ?deathPlaceLabels) ?abstract
WHERE
{
VALUES ?musician { dbr:Nikos_Kazantzakis }
?musician dbo:nationality ?nationality ;
dbo:deathDate ?deathDate ;
dbo:deathPlace/rdfs:label ?deathPlaceLabel ;
dbo:abstract ?abstract .
FILTER(lang(?abstract) = 'en') .
FILTER(lang(?deathPlaceLabel) = 'en') .
} GROUP BY ?musician ?nationality ?deathDate ?abstract
Alternatively, you could try to restrict which kind of death places you want. For example, only cities (with the drawback that it excludes results for which the city is unknown/unspecified).