How to pass a variable to a SERVICE expression in SPARQL? - sparql

I have built an ontology for live concerts, Concert_Ontology.ttl. This contains definitions for concerts, artists, repertoires, and songs. I want to match the artists in my ontology and the artists in the dbpedia Person ontology based on the attributes c:artistName and dbp:name. I have written the following query to access the dbpedia endpoint and retrieve additional information about the artists.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX c: <http://localhost:8080/Concert_Ontology.ttl#>
SELECT ?performer ?artistname ?dob
WHERE {
?performer a c:Artist ;
c:artistName ?artistname .
SERVICE <http://dbpedia.org/sparql> {
?person a dbo:Person ;
dbo:birthDate ?dob ;
dbp:name ?n .
FILTER (str(?n) = ?artistname)
}
}
However, I do not seem to be able to access the ?artistname variable from within the SERVICE expression. If I put the FILTER method outside the SERVICE expression the query works, but since dbpedia has a return cap of 10000 results, I am not able to retrieve and match all the artists.
Could someone guide me in finding a solution to this problem?

I found a solution to my problem. The filter function will not work with a local variable on the remote endpoint. However, if I omit the filter function and simply use the same variable name for the local and remote variable, it will return the correct results. Like this:
SELECT ?performer ?artistname ?dob
WHERE {
?performer a :Performer ;
:artistName ?artistname .
SERVICE <http://dbpedia.org/sparql> {
?person a dbo:Person ;
dbo:birthDate ?dob ;
dbp:name ?artistname .
}
}

SERVICE executes the pattern at the server. The server does not know the value of ?artistname (of which there can be many and is local information to the caller). So the best that can happen is to execute the
?person a dbo:Person ;
dbo:birthDate ?dob ;
dbp:name ?n .
and filter locally.

You can pass variable as IRI to SERVICE.
bind(iri(concat("http://dbpedia.org/resource/",replace(? artistname," ","_"))) as ?person)
and no need to filter by name.

Related

SPARQL query with Apache Jena Fuseki on local database importing geonames

I want to retrieve the name of the city associated to a person in a triplestore which links a person to a geonames entry. I am using a local server (Apache Jena Fuseki) on this minimal triplestore (in turtle):
#prefix ex: <http://www.example.audio/ex> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
#prefix gn: <http://www.geonames.org/ontology#> .
ex:Cristina rdf:type foaf:Person ;
foaf:firstName "Cristina" ;
foaf:based_near <https://sws.geonames.org/3164527/> .
https://sws.geonames.org/3164527/ is the URI of the city of Verona
This is the query I am trying to perform:
SELECT ?person
WHERE {
?person foaf:based_near ?city .
?city gn:name "Verona" .
}
As you can see, what I wish to do is using the gn:name predicate.
How can I achieve this? Obviously I am doing something wrong.

getting labels from Wikidata in graphDB

I have a list of artstyles in graphDB, i am trying to use the SERVICE function to get their labels from Wikidata with this query:
PREFIX gp: <http://www.semanticweb.org/kandd/group76/final_project#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?movement ?label
WHERE{
?artist gp:hasArtStyle ?movement.
SERVICE <https://query.wikidata.org/sparql>{
?movement rdfs:label ?label .
FILTER (langMatches( lang(?label), "EN" ) )
}
}
note that gp is a namespace that only exists in my graph, not anywhere on the internet and also note that ?movement contains a list of valid Wikidata URIs such as http://www.wikidata.org/entity/Q186030
yet still the response I get is:
Error 500: error
Query evaluation error: org.eclipse.rdf4j.query.QueryEvaluationException: org.eclipse.rdf4j.query.QueryEvaluationException: java.io.IOException: Unkown record type: 83 (HTTP status 500)
What am I doing wrong?
Remember that you query is handled from the inside to the outside, meaning that the service part is handled first, and then the part where you use your own specific property.
Currently, your query on WikiData is very general. You ask for everything that has a rdfs:label, and then filter on all the English labels it returns.
Given this, my guess is that you query simply times out. Instead, I would try something like this:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX wd: <http://www.wikidata.org/entity/>
SELECT *
WHERE{
SERVICE <https://query.wikidata.org/sparql>{
?artist wdt:P101 wd:Q186030 ; #Field of Work is contemporary art
wdt:P31 wd:Q5 ; #instance of Human
rdfs:label ?name . #get the label
FILTER (langmatches(lang(?name), "en"))
}
}
If I try this in GraphDB, it returns 156 results.

SPARQL Federated Query Not Returning All Solutions

This is an evolution of this question.
Basically I am having trouble getting all the solutions to a SPARQL query from a remote endpoint. I have read through section 2.4 here because it seems to describe a situation almost identical to mine.
The idea is that I want to filter my results from DBPedia based on information in my local RDF graph. The query is here:
PREFIX ns1:
<http://www.semanticweb.org/caeleanb/ontologies/twittermap#>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT *
WHERE {
?p ns1:displayName ?name .
SERVICE <http://dbpedia.org/sparql> {
?s rdfs:label ?name .
?s rdf:type foaf:Person .
}
}
And the only result I get is dbpedia:John_McCain (for ?s). I think this is because John McCain is the only match in the first 'x' results, but I can't figure out how to get the query to return all matches. For example, if I add a filter like:
SERVICE <http://dbpedia.org/sparql> {
?s rdfs:label ?name .
?s rdf:type foaf:Person .
FILTER(?name = "John McCain"#en || ?name = "Jamie Oliver"#en)
}
Then it correctly returns BOTH dbpedia:Jamie_Oliver and dbpedia:John_McCain. There are dozens of other matches like Jamie Oliver that do not come through unless I specifically add it to a Filter like this.
Can someone explain a way to extract the rest of the matches? Thanks.
It looks like the cause of this issue is that the SERVICE block is attempting to pull all foaf:Persons from DBPedia, and then filter them based on my local Stardog db. Since there is a 10,000 result limit when querying DBPedia, only matches which occur in that set of 10,000 arbitrary Persons will be found. To fix this, I wrote a script to put together a FILTER block containing every string name in my Stardog db and attached it to the SERVICE block to filter remotely and thereby avoid hitting the 10,000 result limit. It looks something like this:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbr: <http://dbpedia.org/resource/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX ns1: <http://www.semanticweb.org/caeleanb/ontologies/twittermap#>
CONSTRUCT{
?s rdf:type ns1:Person ;
ns1:Politician .
}
WHERE {
?s rdfs:label ?name .
?s rdf:type dbo:Politician .
FILTER(?name IN ("John McCain"#en, ...)
}

SPARQL DBpedia - Retrieve Properties with numbers (DatatypeProperties, xsd)

So I encountered a Problem on DBpedia. Apparently I can retrieve any kind of property from a resource with the query below, but when the property is from the type DatatypeProperty or just a number (xsd:integer or something similar) the DBpedia SPARQL Endpoint returns an empty result.
I would like to know what I have to change or even better optional include in my current query to solve this problem.
Important note: Germany and population total are required inputs in my program. Please remember that I must use them.
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT DISTINCT ?objectLabel
WHERE {
?subject ?predicate ?object ; rdfs:label "Germany"#en .
?predicate rdfs:label "population total"#en .
?object rdfs:label ?objectLabel
FILTER (LANG(?objectLabel)='en')
}
Thank you for your help.
A DatatypeProperty is used to related an individual to a literal and literals can't have any outgoing edge, thus, no rdfs:label. If you want to have the lexical form of the literal you can use the str function:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT DISTINCT (str(?object) as ?value)
WHERE {
?subject ?predicate ?object ; rdfs:label "Germany"#en .
?predicate rdfs:label "population total"#en
FILTER (LANG(?objectLabel)='en')
}

Director Filmography - all queries are returning empty

All, I'm trying to get a director's filmography from dbpedia:
Both the queries below (and other attempts not shown) return empty sets. Query below doesn't work:
PREFIX d: <http://dbpedia.org/ontology/>
SELECT ?filmName WHERE {
?film d:director :woody_allen .
?film rdfs:label ?filmName .
}
Or (this is from) :
PREFIX m: <http://data.linkedmdb.org/resource/movie/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?filmTitle WHERE {
?film rdfs:label ?filmTitle.
?film m:director ?dir.
?dir m:director_name "Sofia Coppola".
}
Not sure what would be the problem with such simple queries. Any ideas here?
The problem with your first query is the use of :woody_allen (besides the fact that you haven't actually defined the default prefix and so the query should technically be illegal SPARQL) the term doesn't actually appear in the data as written.
Try rewriting your query like so:
PREFIX d: <http://dbpedia.org/ontology/>
SELECT ?filmName WHERE {
?film d:director <http://dbpedia.org/resource/Woody_Allen> .
?film rdfs:label ?filmName .
}
The above does give results.
As for your second query DBPedia does not use the Linked MDB ontologies so that query can't match anything