GraphDB - Federated Query - sparql

I would like to know how to perform a federated search on GraphDB. For example, to insert the code below in GraphDB, how should I do it? The idea is to add the content below to my local GraphDB.
#Locations of air accidents in wikidata - https://query.wikidata.org/
SELECT ?label ?coord ?place
WHERE
{
?subj wdt:P31 wd:Q744913 .
?subj wdt:P625 ?coord .
?subj rdfs:label ?label
filter (lang(?label) = "en")
}

Posting #UninformedUser's comment as an answer for better readability.
SPARQL 1.1 offers the SERVICE feature, described here. You can use it to perform federated queries against Wikidata directly inside of GraphDB.
SELECT * WHERE {
SERVICE <https://query.wikidata.org/sparql> {
?subj wdt:P31 wd:Q744913 ;
wdt:P625 ?coord ;
rdfs:label ?label
FILTER (lang(?label) = "en")
}
}

To insert the data to your local GraphDB, use something like this:
INSERT {
?subj wdt:P31 wd:Q744913 ;
wdt:P625 ?coord ;
rdfs:label ?label
} WHERE {
SERVICE <https://query.wikidata.org/sparql> {
?subj wdt:P31 wd:Q744913 ;
wdt:P625 ?coord ;
rdfs:label ?label
FILTER (lang(?label) = "en")
}
}
However, you'd probably want to unpack the coordinates and use some ontology that's easier to understand, eg:
PREFIX wgs: <http://www.w3.org/2003/01/geo/wgs84_pos#> # see http://prefix.cc/wgs.sparql
INSERT {
?subj a :AirAccident;
wgs:lat ?lat; wgs:long ?long;
rdfs:label ?label
} WHERE {
SERVICE <https://query.wikidata.org/sparql> {
?subj wdt:P31 wd:Q744913 ;
p:P625/psv:P625 [wikibase:geoLatitude ?lat; wikibase:geoLongitude ?long];
rdfs:label ?label
FILTER (lang(?label) = "en")
}
}
For the p:P625, psv:P625, wikibase:geoLatitude stuff, see https://github.com/nichtich/wdq#wikidata-ontology (and if you install it, wdq help ontology gives this color-coded)

Related

How to query wikidata using SPARQL to find a place that matches certain criteria and is geographically near another city

I wrote the following SPARQL query to find the wikidata item with the label "San Leucio" in Italy.
SELECT DISTINCT * WHERE {
?location ?label 'San Leucio'#en .
?location wdt:P17 wd:Q38 .
?location rdfs:label ?locationName .
OPTIONAL {
?article schema:about ?location .
?article schema:isPartOf <https://en.wikivoyage.org/> .
}
?location wdt:P18 ?image .
FILTER(lang(?locationName) = "en")
}
The query returns these 3 results:
wd:Q55179410
wd:Q20009063
wd:Q846499
The result I want is wd:Q846499, which is outside of Naples, Italy. Is there any way I could further filter this query to return the result that is nearest to Naples? I know that I can get the geoCoordinates for each of these with ?location wdt:P625 ?coordinates, but I'm not sure how I could use that to compare to the geo-coordinates of Naples to get what I want.
SELECT DISTINCT * {
VALUES ?naples {wd:Q2634}
?Napfes wdt:P625 ?naples_coordinates.
?location rdfs:label 'San Leucio'#en .
?location wdt:P17 wd:Q38 .
?location wdt:P18 ?image .
?location wdt:P625 ?location_coordinates.
OPTIONAL {
?article schema:about ?location .
?article schema:isPartOf <https://en.wikivoyage.org/> .
}
BIND (geof:distance(?location_coordinates, ?naples_coordinates) AS ?distance)
} ORDER BY ?distance LIMIT 1

Aggregate properties

I'm developing my own Fuseki endpoint from some DBpedia data.
I'm in doubt on how to aggregate properties related to a single resource.
SELECT ?name ?website ?abstract ?genre ?image
WHERE{
VALUES ?s {<http://dbpedia.org/resource/Attack_Attack!>}
?s foaf:name ?name ;
dbo:abstract ?abstract .
OPTIONAL { ?s dbo:genre ?genre } .
OPTIONAL { ?s dbp:website ?website } .
OPTIONAL { ?s dbo:image ?image } .
FILTER LANGMATCHES(LANG(?abstract ), "en")
}
SPARQL endpoint: http://dbpedia.org/sparql/
This query returns 2 matching results. They are different just for the dbo:genre value. There is a way I can query the knowledge base and retrieving a single result with a list of genres?
#chrisis's query works well on the DBpedia SPARQL Endpoint, which is based on Virtuoso.
However, if you are using Jena Fuseki, you should use more conformant syntax:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
SELECT
?name
(SAMPLE(?website) AS ?sample_website)
(SAMPLE(?abstract) AS ?sample_abstract)
(SAMPLE(?image) AS ?sample_image)
(GROUP_CONCAT(?genre; separator=', ') AS ?genres)
WHERE {
VALUES (?s) {(<http://dbpedia.org/resource/Attack_Attack!>)}
?s foaf:name ?name ;
dbo:abstract ?abstract .
OPTIONAL { ?s dbo:genre ?genre } .
OPTIONAL { ?s dbp:website ?website } .
OPTIONAL { ?s dbo:image ?image} .
FILTER LANGMATCHES(LANG(?abstract ), "en")
} GROUP BY ?name
The differences from the #chrisis's query are:
Since GROUP_CONCAT is an aggregation function, it might be used with GROUP BY only;
Since GROUP BY is used, all non-grouping variables should be aggregated (e.g. via SAMPLE);
GROUP_CONCAT syntax is slightly different.
In Fuseki, these AS in the projection are in fact superfluous: see this question and comments.
Yes, the GROUP_CONCAT() function is what you want.
SELECT ?name ?website ?abstract (GROUP_CONCAT(?genre,',') AS ?genres) ?image
WHERE{
<http://dbpedia.org/resource/Attack_Attack!> a dbo:Band ;
foaf:name ?name;
dbo:abstract ?abstract .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbo:genre ?genre } .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbp:website ?website} .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbo:image ?image} .
FILTER LANGMATCHES(LANG(?abstract ), "en")
}

How to use Sparql Contains to match similar String?

I'm trying to grab some definition in dbpedia inside my thesaurus.
Although can find country that have a label that match my country, i don't get all of them. So i try to match similar label with contains but it does not work.
Any idea why.
SELECT distinct ?idbcountry ?label ?labelDb ?def
WHERE {
?idbcountry a skos:Concept .
?idbcountry rdfs:label ?label .
?idbcountry skos:inScheme iadb:IdBCountries .
FILTER(lang(?label) = "en")
Service <http://dbpedia.org/sparql> {
?s a <http://dbpedia.org/ontology/Country> .
?s rdfs:label ?labelDb .
FILTER(CONTAINS (?labelDb, ?label)).
?s rdfs:comment ?def .
FILTER(lang(?def) = "en") .
FILTER(lang(?labelDb) = "en") .
}}
The exact matching query that works is as follows:
SELECT distinct ?idbcountry ?label ?def
WHERE {
?idbcountry a skos:Concept .
?idbcountry rdfs:label ?label .
?idbcountry skos:inScheme iadb:IdBCountries .
FILTER(lang(?label) = "en")
Service <http://dbpedia.org/sparql> {
?s a <http://dbpedia.org/ontology/Country> .
?s rdfs:label ?label .
?s rdfs:comment ?def
FILTER(lang(?def) = "en")
}
}
EDIT1
Data Samples:
<http://thesaurus.iadb.org/publicthesauri/10157002136735779158437>
rdf:type skos:Concept ;
dct:created "2015-03-27T16:43:48.052-04:00"^^xsd:dateTime ;
rdfs:label "BO"#en ;
rdfs:label "Bolivia"#en ;
rdfs:label "Bolivia"#es ;
rdfs:label "Bolivie"#fr ;
rdfs:label "Bolívia"#pt ;
skos:altLabel "BO"#en ;
skos:definition "Bolivia (/bəˈlɪviə/, Spanish: [boˈliβja], Quechua: Buliwya, Aymara: Wuliwya), officially known as the Plurinational State of Bolivia (Spanish: Estado Plurinacional de Bolivia locally: [esˈtaðo pluɾinasjoˈnal de βoˈliβja]), is a landlocked country located in western-central South America."#en ;
skos:inScheme :IdBCountries ;
skos:prefLabel "Bolivia"#en ;
skos:prefLabel "Bolivia"#es ;
skos:prefLabel "Bolivie"#fr ;
skos:prefLabel "Bolívia"#pt ;
skos:topConceptOf :IdBCountries ;
<http://xmlns.com/foaf/0.1/focus> <http://dbpedia.org/resource/Bolivia> ;
Without seeing your data, we can't know why your query isn't working. However, using contains is pretty straightforward. It's just a matter of contains(string,substring). As Jeen said, we can't reproduce your problem without knowing what your data looks like, but here's an example of contains in action:
select distinct ?country ?label {
?country a dbpedia-owl:Country ; #-- select countries
rdfs:label ?label . #-- and get labels
filter langMatches(lang(?label),"en") #-- but only English labels
filter contains(?label,"land") #-- containing "land"
}
SPARQL results

Getting super and sub classes of Dbpedia Ontology

I am trying to get the hierarchy of super and subclass of dbpedia ontolgy.
Sparql query:
SELECT DISTINCT ?superclass ?subclass
WHERE
{
?subclass a owl:Class .
?subclass rdfs:subClassOf ?superclass
}
ORDER BY ?superclass ?subclass
It gives me all classes. But when I am trying to get the counts of entity inside classes. Some classes have entity while some don't have.
Sparql query to get the count of entity inside classes.
Getting Entities:
SELECT DISTINCT ?label AS ?label
?name AS ?name
?link AS ?link
WHERE
{
?link rdf:type <http://www.wikidata.org/entity/Q12136> .
OPTIONAL { ?link foaf:name ?name }
OPTIONAL { ?link rdfs:label ?label }
FILTER( lang(?label) = "en" )
}
Not getting Entities:
SELECT DISTINCT ?label AS ?label
?name AS ?name
?link AS ?link
WHERE
{
?link rdf:type <http://www.wikidata.org/entity/Q18553493> .
OPTIONAL { ?link foaf:name ?name }
OPTIONAL { ?link rdfs:label ?label }
FILTER(lang(?label) = "en" )
}
Why some classes don't have entities? Or Am I doing something wrong? Any help please?
First of all, you are talking about classes and not ontologies. I don't know why you think that entities are instances of ontologies, especially when you're talking about individuals/instances/resources.
Second, why shouldn't there be classes that do not have instances yet?

SPARQL entity lists inside select queries

In the following DBpedia query, is there a way to consolidate the UNIONs into a single pattern?
PREFIX prop: <http://resedia.org/ontology/>
PREFIX res: <http://resedia.org/resource/>
SELECT DISTINCT ?language ?label
WHERE {
{res:Spain prop:language ?language}
UNION
{res:France prop:language ?language}
UNION
{res:Italy prop:language ?language}
?language rdfs:label ?label .
FILTER langMatches(lang(?label), "en")
}
The SPARQL spec mentions something about RDF collections but I don't really understand what it's describing. It seemed like the following syntax should work, but it didn't.
PREFIX prop: <http://resedia.org/ontology/>
PREFIX res: <http://resedia.org/resource/>
SELECT DISTINCT ?language ?label
WHERE {
(res:Spain res:France res:Italy) prop:language ?language
?language rdfs:label ?label .
FILTER langMatches(lang(?label), "en")
}
Is there a way to define a list (or "multiset", or "bag") of URIs like this inside a SELECT query?
In SPARQL 1.1 you can do
SELECT DISTINCT ?language ?label
WHERE {
?country prop:language ?language .
?language rdfs:label ?label .
VALUES ?country { res:Spain res:France res:Italy }
FILTER langMatches(lang(?label), "en")
}
Simple answer: no.
(res:Spain res:France res:Italy) prop:language ?language
means 'match where a list containing Spain, France and Italy has a language', i.e. the list itself has a language.
You could do:
?country prop:language ?language . ?language rdfs:label ?label .
FILTER ( ?country == res:Spain || ?country == res:France || ?country == res:Italy )
which is shorter, but may be slower.
(I had a feeling SPARQL 1.1 had an 'IN' feature, but I don't see it in the drafts)