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
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.
I’m trying to make a rather complex call to DBPedia using a SPARQL query. I’d like to get some information about a city (district, federal state/»Bundesland«, postal codes, coordinates and geographically related cities).
Try online!
SELECT * WHERE {
#input
?x rdfs:label "Bentzin"#de.
#district
OPTIONAL {
?x dbpedia-owl:district ?district
# ?x dbpprop:landkreis ?district
{ SELECT * WHERE {
?district rdfs:label ?districtName
FILTER(lang(?districtName) = "de")
?district dbpprop:capital ?districtCapital
{ SELECT * WHERE {
?districtCapital rdfs:label ?districtCapitalName
FILTER(lang(?districtCapitalName) = "de")
}}
}}
}
#federal state
OPTIONAL {
# ?x dbpprop:bundesland ?land
?x dbpedia-owl:federalState ?land
{ SELECT * WHERE {
?land rdfs:label ?landName
FILTER(lang(?landName) = "de")
}}
}
#postal codes
?x dbpedia-owl:postalCode ?zip.
#coordinates
?x geo:lat ?lat.
?x geo:long ?long
#cities in the south
OPTIONAL {
?x dbpprop:south ?south
{SELECT * WHERE {
?south rdfs:label ?southName
FILTER(lang(?southName) = "de")
}}
}
#cities in the north
OPTIONAL {
?x dbpprop:north ?north
{ SELECT * WHERE {
?north rdfs:label ?northName
FILTER(lang(?northName) = "de")
}}
}
#cities in the west
...
}
This works in some cases, however, there are a few major problems.
There are several different properties that may contain the value for the federal state or district. Sometimes it’s dbpprop:landkreis (the german word for district, in other cases it’s dbpedia-owl:district. Is it possible to combine those two in cases where only one of them is set?
Further, I’d like to read out the names of the cities in the north, northwest, …. Sometimes, these cities are referenced in dbpprop:north etc. The basic query for each direction is the same:
OPTIONAL {
?x dbpprop:north ?north
{ SELECT * WHERE {
?north rdfs:label ?northName
FILTER(lang(?northName) = "de")
}}
}
I really don’t want to repeat that eight times for every direction, is there any way to simplify this?
Sometimes, there are multiple other cities referenced (example). In those cases, there are multiple datasets returned. Is there any possibility to get a list of the names of those cities in a single dataset instead?
+---+---+---------------------------------------------------------------+
| x | … | southName |
+---+---+---------------------------------------------------------------+
| … | … | "Darmstadt"#de, "Stuttgart"#de, "Karlsruhe"#de, "Mannheim"#de |
+---+---+---------------------------------------------------------------+
Your feedback and your ideas are greatly appreciated!
Till
There are several different properties that may contain the value for the federal state or district. Sometimes it’s dbpprop:landkreis (the
german word for district, in other cases it’s dbpedia-owl:district. Is
it possible to combine those two in cases where only one of them is
set?
SPARQL property paths are great for this. You can just say
?subject dbprop:landkreis|dbpedia-owl:district ?district
If there are more properties, you'll probably prefer a version with values:
values ?districtProperty { dbprop:landkreis dbpedia-owl:district }
?subject ?districtProperty ?district
Further, I’d like to read out the names of the cities in the north,
northwest, …. Sometimes, these cities are referenced in dbpprop:north
etc. The basic query for each direction is the same:
OPTIONAL {
?x dbpprop:north ?north
{ SELECT * WHERE {
?north rdfs:label ?northName
FILTER(lang(?northName) = "de")
}}
}
Again, it's values to the rescue. Also, don't use lang(…) = … to filter languages, use langMatches:
optional {
values ?directionProp { dbpprop:north
#-- ...
dbpprop:south }
?subject ?directionProp ?direction
optional {
?direction rdfs:label ?directionLabel
filter langMatches(lang(?directionLabel),"de")
}
}
Sometimes, there are multiple other cities referenced (example). In
those cases, there are multiple datasets returned. Is there any
possibility to get a list of the names of those cities in a single
dataset instead?
+---+---+---------------------------------------------------------------+
| x | … | southName |
+---+---+---------------------------------------------------------------+
| … | … | "Darmstadt"#de, "Stuttgart"#de, "Karlsruhe"#de, "Mannheim"#de |
+---+---+---------------------------------------------------------------+
That's what group by and group_concat are for. See Aggregating results from SPARQL query. I don't actually see these results in the query you gave though, so I don't have good data to test a result with.
You also seem to be doing a lot of unnecessary subselects. You can just put additional triples in the graph pattern; you don't need a nested query to get additional information.
With those considerations, your query becomes:
select * where {
?x rdfs:label "Bentzin"#de ;
dbpedia-owl:postalCode ?zip ;
geo:lat ?lat ;
geo:long ?long
#-- district
optional {
?x dbpedia-owl:district|dbpprop:landkreis ?district .
?district rdfs:label ?districtName
filter langMatches(lang(?districtName),"de")
optional {
?district dbpprop:capital ?districtCapital .
?districtCapital rdfs:label ?districtCapitalName
filter langMatches(lang(?districtCapitalName),"de")
}
}
#federal state
optional {
?x dbpprop:bundesland|dbpedia-owl:federalState ?land .
?land rdfs:label ?landName
filter langMatches(lang(?landName),"de")
}
values ?directionProp { dbpprop:south dbpprop:north }
optional {
?x ?directionProp ?directionPlace .
?directionPlace rdfs:label ?directionName
filter langMatches(lang(?directionName),"de")
}
}
SPARQL results
Now, if you're just looking for the names of these things, without the associated URIs, you can actually use property paths to shorten a lot of the results that retrieve labels. E.g.:
select * where {
?x rdfs:label "Bentzin"#de ;
dbpedia-owl:postalCode ?zip ;
geo:lat ?lat ;
geo:long ?long
#-- district
optional {
?x (dbpedia-owl:district|dbpprop:landkreis)/rdfs:label ?districtName
filter langMatches(lang(?districtName),"de")
optional {
?district dbpprop:capital/rdfs:label ?districtCapitalName
filter langMatches(lang(?districtCapitalName),"de")
}
}
#-- federal state
optional {
?x (dbpprop:bundesland|dbpedia-owl:federalState)/rdfs:label ?landName
filter langMatches(lang(?landName),"de")
}
optional {
values ?directionProp { dbpprop:south dbpprop:north }
?x ?directionProp ?directionPlace .
?directionPlace rdfs:label ?directionName
filter langMatches(lang(?directionName),"de")
}
}
SPARQL results
In order to determine the number of classes in a .owl file,
I was advised to use the following SPARQL query:
SELECT ( count(?class) as ?count )
WHERE { graph <put_your_model_graph_name_here> { ?class a owl:Class . } }
However, when I replace the put_your_model_graph_name_here with my ontology IRI, I get 0
I also tried http://blahblahblah followed immediately by # to no avail.
What am I doing wrong?
Difficult to tell without seeing how you are loading and querying the data. Try using:
SELECT ( count(?class) as ?count ) { ?class a owl:Class }
which will query the default graph, or
SELECT ?g ( count(?class) as ?count )
{ graph ?g { ?class a owl:Class } }
group by ?g
which will give counts for all the named graphs.
I am trying to somehow find all the owl:sameAs properties from a resource link. A simple query would be like
SELECT ?x WHERE {
<http://dbpedia.org/resource/Tetris> owl:sameAs ?x
}
However i also would like to get the Yago link mentioned as is owl:sameAs of. Could any one help me out how to do this ?
You can get the YAGO link like so:
SELECT ?x WHERE {
?x owl:sameAs <http://dbpedia.org/resource/Tetris>
}
Or get both the “incoming” and “outgoing” links in one query:
SELECT ?x WHERE {
{ <http://dbpedia.org/resource/Tetris> owl:sameAs ?x }
UNION
{ ?x owl:sameAs <http://dbpedia.org/resource/Tetris> }
}