DBPedia Sparql with one request get links for multiple resources - sparql

Currently I'm doing for every entity that I have a single request to the sparql endpoint to get all the links for it e.g.
SELECT * WHERE {
{<http://dbpedia.org/resource/San_Francisco> rdf:type ?link}
}
I want to make it more efficient, and I would like to know if there is a way to get the links for multiple entities with one request. I threw something together but this gives me just a big list with all the links.
SELECT * WHERE {
{<http://dbpedia.org/resource/San_Francisco> rdf:type ?link}
UNION
{<http://dbpedia.org/resource/Silicon_Valley> rdf:type ?link}
}
Can I somehow get the links, so I can identify to which entity they belong?

You can be a little more succinct with the SPARQL 1.1 values keyword:
SELECT *
WHERE
{ VALUES ?entity { <http://dbpedia.org/resource/San_Francisco>
<http://dbpedia.org/resource/Silicon_Valley> }
?entity rdf:type ?link
}
Do you want a distinct list? Maybe sort the list and add English-language labels if available?
SELECT DISTINCT ?link ?llab
WHERE
{ VALUES ?entity { <http://dbpedia.org/resource/San_Francisco>
<http://dbpedia.org/resource/Silicon_Valley> }
?entity rdf:type ?link
OPTIONAL
{ ?link rdfs:label ?llab
FILTER ( lang(?llab) = "en" )
}
}
ORDER BY ?link

Related

Query for resources using their URIs

I have a bunch of resource URIs, and I need the property values related to each of them. For a single resource, say <http://my.url/res#resourceUri>, I can write this query:
PREFIX v: <http://my.url/res#>
SELECT ?name
WHERE {
<http://my.url/res#resourceUri> a v:t;
rdfs:label ?name .
}
For multiple resources, I can use UNION, like this:
PREFIX v: <http://my.url/res#>
SELECT ?name
WHERE {
{ <http://my.url/res#resourceUri> a v:t; rdfs:label ?name } UNION
{ <http://my.url/res#anotherResource> a v:t; rdfs:label ?name }
}
Is there a way to write a shorter, leaner version of this second query?
You can use values for this. Your example would be written as
PREFIX v: <http://my.url/res#>
SELECT ?resource ?name WHERE {
values ?resource { <http://my.url/res#resourceUri>
<http://my.url/res#anotherResource> }
?resource a v:t;
rdfs:label ?name
}
The question is different, but the answer to how to use Union/or in sparql path with arbitrary length? is similar.

SPARQL query: How to have a new "null" element for each result

i'm making a project using .csv files that the DBpedia Sparql endpoint creates.
For the normal query there's no problem, i use this one for have the results:
SELECT ?museum, ?artwork, ?abstract, ?thumbnail WHERE {
?museum <http://dbpedia.org/ontology/address> ?address.
?artwork <http://dbpedia.org/ontology/location> ?museum.
?artwork <http://dbpedia.org/ontology/abstract> ?abstract.
?artwork <http://dbpedia.org/ontology/thumbnail> ?thumbnail.
FILTER contains(?address, "Roma")
}
and it generates a table (museum - artwork - abstract .thumblink) ...
I would like to know if it's possible to have the same table with a element added like
table (museum - artwork - abstract - thumblink - personal_element_code)
all the new element are good if they are null...
Thanks in advance
UPDATE
i've made a poit using this "kind" of query
SELECT ?museum ?artwork ?abstract ('null' as ?beacon_code) WHERE {
?museum <http://dbpedia.org/ontology/address> ?address.
?artwork <http://dbpedia.org/ontology/location> ?museum.
?artwork <http://dbpedia.org/ontology/abstract> ?abstract.
FILTER contains(?address, "Firenze")
}
note: do not flag: "Strict checking of void variables"
It's kind barbaric but it works
As written, your query isn't actually legal SPARQL. There should not be commas between your projection variables. DBpedia's endpoint, Virtuoso, is notorious for allowing some non-standard syntax. It's particularly frustrating because if your client has to parse your query first, then something you try in the DBpedia webservice directly might not work with your client library. You can check queries at sparql.org's query validator.
In SPARQL, you can select variables that don't appear in your query, and they should have a sort of null value. That is, you should simply be able to do:
SELECT ?museum ?artwork ?abstract ?thumbnail ?personal_element_code WHERE {
However, that doesn't actually work on the DBpedia endpoint (again, a Virtuoso oddity). E.g., if you try the following query, you get the following error:
select ?person ?x where {
?person a dbpedia-owl:Person
}
limit 10
Virtuoso 37000 Error SP031: SPARQL compiler: Variable 'x' is used in the query result set but not assigned
However, you can work around this without too much trouble. Just use values ?x { undef } in the body of the query. E.g.:
select ?person ?x where {
values ?x { undef }
?person a dbpedia-owl:Person
}
limit 10
SPARQL results
If you request CSV for that, you'll get back the following, which has the empty column that you're looking for:
"person","x"
"http://dbpedia.org/resource/%C3%81ngel_Gim%C3%A9nez",
"http://dbpedia.org/resource/Aaron_Lines",
"http://dbpedia.org/resource/Abel_Lafleur",
"http://dbpedia.org/resource/Ada_Maimon",
"http://dbpedia.org/resource/Adam_Krikorian",
"http://dbpedia.org/resource/Albert_Constable",
"http://dbpedia.org/resource/Alex_Reid_(actress)",
"http://dbpedia.org/resource/Alex_Reid_(art_dealer)",
"http://dbpedia.org/resource/Alex_Reid_(fighter)",
"http://dbpedia.org/resource/Alex_Reid_(footballer)",
If you actually just want the string null, this is all much easier. You can just ('null' as ?x). E.g.:
select ?person ('null' as ?x) where {
values ?x { undef }
?person a dbpedia-owl:Person
}
limit 10
SPARQL results
"person","x"
"http://dbpedia.org/resource/%C3%81ngel_Gim%C3%A9nez","null"
"http://dbpedia.org/resource/Aaron_Lines","null"
"http://dbpedia.org/resource/Abel_Lafleur","null"
"http://dbpedia.org/resource/Ada_Maimon","null"
"http://dbpedia.org/resource/Adam_Krikorian","null"
"http://dbpedia.org/resource/Albert_Constable","null"
"http://dbpedia.org/resource/Alex_Reid_(actress)","null"
"http://dbpedia.org/resource/Alex_Reid_(art_dealer)","null"
"http://dbpedia.org/resource/Alex_Reid_(fighter)","null"
"http://dbpedia.org/resource/Alex_Reid_(footballer)","null"
The way to treat data items that may be present, or may not, is to use OPTIONAL.
e.g.
SELECT ?museum ?artwork ?abstract ?thumbnail WHERE {
?museum <http://dbpedia.org/ontology/address> ?address.
?artwork <http://dbpedia.org/ontology/location> ?museum.
FILTER contains(?address, "Roma")
OPTIONAL{?artwork <http://dbpedia.org/ontology/abstract> ?abstract.}
OPTIONAL{?artwork <http://dbpedia.org/ontology/thumbnail> ?thumbnail.}
}

retrieve list of mathematics categories from dbpedia?

Is there a way using SPARQL to retrieve all topics of in dpbedia?
http://dbpedia.org/snorql/
That is to say is there a way to extract all the subfields of the topics listed here:
http://en.wikipedia.org/wiki/Lists_of_mathematics_topics
The broad topics are lists here: http://dbpedia.org/page/Category:Fields_of_mathematics
I would like a list which shows the parent class and its subfield.
question 1:
depends on how you define topic....
you can query for instance for skos:Concept:
SELECT ?con
WHERE {
?con a skos:Concept
}
limit 1000
see result
question 2:
you can query for skos:broader properties, like:
SELECT ?parent (?label as ?sub)
WHERE {
{
?sub skos:broader <http://dbpedia.org/resource/Category:Fields_of_mathematics> .
?sub rdfs:label ?label .
} UNION {
<http://dbpedia.org/resource/Category:Fields_of_mathematics> rdfs:label ?parent
}
}
see results
retrieve a list of the next level of sub-fields of the above fields with:
SELECT ?parent ?sub ?subsub
WHERE {
{
?sub skos:broader <http://dbpedia.org/resource/Category:Fields_of_mathematics> .
OPTIONAL {?subsub dcterms:subject ?sub}
} UNION {
<http://dbpedia.org/resource/Category:Fields_of_mathematics> rdfs:label ?parent
}
}
see results

Is there a way to use a variable without returning it with SPARQL "select *"?

Is there some way to use a kind of placeholder variable with SPARQL without returning it when using SELECT * ?
For example:
SELECT * WHERE {
?s dcterms:title ?title;
foaf:person ?name.
?s2 :inProject ?s.
}
Where I would not want to return the ?s variable, just the ?title, ?name, and ?s2 variables while leaving the SELECT *.
I understand I can limit the select results by using SELECT ?title ?name ..., but I'm just curious if there is some kind of notation for placeholder variables or some way to manage this.
EDIT:
I understand you can use blank nodes to accomplish this in some cases, for example:
SELECT * WHERE {
_:s dcterms:title ?title;
foaf:person ?name.
?s2 :inProject _:s.
}
However, doesn't this cause problems since blank nodes can't be used across basic graph patterns? For example, this breaks in the case:
SELECT * WHERE {
_:s dcterms:title ?title;
foaf:person ?name.
OPTIONAL { ?s2 :inProject _:s. }
}
Thanks!
For variables scoped to a single pattern yes, use the blank node variable syntax as you demonstrated in your question
In the general case no, if you use a variable then SELECT * will return it.
One possible workaround is to use sub-queries where you do list variables and leave out the variables you don't want e.g.
SELECT * WHERE
{
{
SELECT ?title ?name ?s2 WHERE
{
?s dcterms:title ?title;
foaf:person ?name.
OPTIONAL{ ?s2 :inProject ?s. }
}
}
}
But then I assume this is exactly what you are trying to avoid since you end up listing variables anyway.

extract city data from dbpedia or LinkedGeoData

I'm trying now for a couple of hours to figure out how to get various informations out of dbpedia or LinkedGeoData.
I used this interface (http://dbpedia.org/snorql) and tried a different approaches, but I never got the result that I need.
If I use something lik this:
SELECT * WHERE {
?subject rdf:type <http://dbpedia.org/ontology/City>.
OPTIONAL {
?subject <http://dbpedia.org/ontology/populationTotal> ?populationTotal.
}
OPTIONAL {
?subject <http://dbpedia.org/ontology/populationUrban> ?populationUrban.
}
OPTIONAL {
?subject <http://dbpedia.org/ontology/areaTotal> ?areaTotal.
}
OPTIONAL {
?subject <http://dbpedia.org/ontology/populationUrbanDensity> ?populationUrbanDensity.
}
OPTIONAL {
?subject <http://dbpedia.org/ontology/isPartOf> ?isPartOf.
}
OPTIONAL {
?subject <http://dbpedia.org/ontology/country> ?country.
}
OPTIONAL {
?subject <http://dbpedia.org/ontology/utcOffset> ?utcOffset.
}
OPTIONAL {
?subject <http://dbpedia.org/property/janHighC> ?utcOffset.
}
OPTIONAL {
?subject <http://dbpedia.org/property/janLowC> ?utcOffset.
}
}
LIMIT 20
I run out of limits.
I also tried this:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT * WHERE {
?subject rdf:type <http://dbpedia.org/ontology/City>.
?subject rdfs:label ?label.
FILTER ( lang(?label) = 'en'
}
LIMIT 100
But that give me en error, which I don't understand. If I remove the FILTER, it works but give me the labels in all languages...
What I'm looking for is something like this http://dbpedia.org/page/Vancouver
But not all the data, but some of it like population, area, coutry, elevation, lat, long, timezone, label#en, abstract#en etc.
Can someone help me to get working syntax?
Thanks for y'all help.
UPDATE:
I got it to work so far with:
SELECT DISTINCT *
WHERE {
?city rdf:type dbpedia-owl:Settlement ;
rdfs:label ?label;
dbpedia-owl:abstract ?abstract ;
dbpedia-owl:populationTotal ?pop ;
dbpedia-owl:country ?country ;
dbpprop:website ?website .
FILTER ( lang(?abstract) = 'en' && lang(?label) = 'en')
}
LIMIT 20
But still running out of limits if I want to get all settlements. Btw. is there a way to get all cities and settlements in one table?
By "run out of limits", do you mean the error "Bandwidth Limit Exceeded URI = '/!sparql/'"? I guess this is a limit set by dbpedia to make sure that it is not flooded with queries that take "forever" to run, and if so, then there is probably not so much you can do. You can ask for data in chunks, using OFFSET, LIMIT and ORDER BY, see http://www.w3.org/TR/rdf-sparql-query/#modOffset.
UPDATE: Yes, this seems to be the way to go: http://www.mail-archive.com/dbpedia-discussion#lists.sourceforge.net/msg03368.html
In the second query the error is a missing parenthesis. This
FILTER ( lang(?label) = 'en'
should be
FILTER ( lang(?label) = 'en')
For your last question, a natural way to collect multiple things/(similiar queries) in one query/table is using UNION, e.g.,
SELECT ?x
WHERE {
{ ?x rdf:type dbpedia-owl:City }
UNION
{ ?x rdf:type dbpedia-owl:Settlement }
}