Search code examples
rdfsparqljenasemantic-webdbpedia

Sparql: list Steven Spielberg's films on dbpedia.org


Example output, use http://dbpedia.org/page/Steven_Spielberg as example

format: film_name, screen_player(zero to more, separated by "|"), producer(zero to more, separated by "|")

Example output 1: Hook_(film), Frank Marshall|Kathleen Kennedy|Gerald R. Molen, James V. Hart|Malia Scotch Marmo

Example output 2: Jaws_(film), Richard D. Zanuck|David Brown, Peter Benchley|Carl Gottlieb

enter image description here

End point http://dbpedia.org/sparql

My query so far, which is far from the example 1 and example 2.

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX dbpprop: <http://dbpedia.org/property/>
PREFIX dbres: <http://dbpedia.org/resource/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
select
?filmName,
(GROUP_CONCAT(?producerName ; SEPARATOR = "|") AS ?producerNames),
(GROUP_CONCAT(?screenPlayerName ; SEPARATOR = "|") AS ?screenPlayerNames)
where {
?film dbpedia-owl:director dbres:Steven_Spielberg .
?film rdfs:label ?filmName .

optional {        
?film dbpprop:screenplay ?screenPlayer .
?screenPlayer foaf:name ?screenPlayerName .         
}

optional {
?film dbpedia-owl:producer ?producer .
?producer foaf:name ?producerName .
}
}
order by
?filmName

My question: basically, I need to display all Steven Spielberg's movies like the two examples above.


Solution

  • Try:

    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
    PREFIX dbpprop: <http://dbpedia.org/property/>
    PREFIX dbres: <http://dbpedia.org/resource/>
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    
    SELECT
    ( CONCAT ( SAMPLE(?filmName) , " , ", 
               GROUP_CONCAT(DISTINCT ?producerName ; SEPARATOR = "|"), " , ",
               GROUP_CONCAT(DISTINCT ?screenPlayerName ; SEPARATOR = "|")
             ) AS ?formatted )
    WHERE
    {
        ?film dbpedia-owl:director dbres:Steven_Spielberg .
        ?film rdfs:label ?filmName .
    
        optional {        
            ?film dbpprop:screenplay ?screenPlayer .
            ?screenPlayer foaf:name ?screenPlayerName .         
        }
    
        optional {
            ?film dbpedia-owl:producer ?producer .
            ?producer foaf:name ?producerName .
        }
    
        FILTER (lang(?filmName) = 'en')
    }
    GROUP BY ?film
    

    Try the query out

    The bulk of the work is in the SELECT expression, which CONCATs the various elements together.

    The other change is GROUP BY ?film which collects together the elements so there is one row per film. We have to SAMPLE(?filmName) because of this: there may be more than one name. (In fact most films have multiple names due to different languages, which we suppress with a filter)