Sparql - Applying limiting criteria to predicates - sparql

I'm fairly new to RDF / Sparql, so apologies for any incorrect terminology, and also for the fairly terrible example that follows:
Given the following RDF dataset:
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix e: <http://www.example.com/#> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
e:Freemason a owl:Class .
e:Civilian a owl:Class .
e:Marty a e:Freemason .
e:Eugene a e:Freemason .
e:Mike a e:Freemason .
e:Alan a e:Freemason .
e:Paul a e:Civilian .
e:Marty foaf:knows e:Eugene .
e:Eugene foaf:knows e:Mike .
e:Eugene foaf:knows e:Paul .
e:Paul foaf:knows e:Alan .
I'm trying to identify friends-of-friends that e:Marty knows through other e:Freemasons only.
So:
Marty knows Mike through Eugene, and they're all Freemason's so it's fine
Marty knows Eugene, who has a Civilian friend Paul. Paul has a Freemason friend Alan. However, Marty doesn't have a "freemason only" path to Alan, so he should be excluded.
Here's the SPARQL query I have:
prefix e: <http://www.example.com/#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
SELECT *
{
<http://www.example.com/#Marty> foaf:knows+ ?target .
?target a e:Freemason .
}
This returns:
http://www.example.com/#Eugene
http://www.example.com/#Mike
http://www.example.com/#Alan
Here, Alan is included as he matches the is-a-freemason criteria.
How I do modify the query to exclude Alan?

I don't know the solution in pure SPARQL, sorry.
In OpenLink Virtuoso's SPARQL-BI, the solution is this query
prefix e: <http://www.example.com/#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
select *
where
{
{ select ?orig ?target
where
{ ?orig foaf:knows ?target .
?target a e:Freemason .
}
}
option ( TRANSITIVE,
T_IN(?orig),
T_OUT(?target),
T_DISTINCT,
T_MIN(1)
)
filter ( ?orig = <http://www.example.com/#Marty> )
}
-- with these results --
orig target
<http://www.example.com/#Marty> <http://www.example.com/#Eugene>
<http://www.example.com/#Marty> <http://www.example.com/#Mike>

Here's an example using SPARQL that has been deprecated from the spec (for reasons I never understood) but remains supported in Virtuoso (which will be the case for the unforeseeable future)
## RDF-Turtle Start ##
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix e: <http://www.example.com/#> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
e:Freemason a owl:Class .
e:Civilian a owl:Class .
e:Marty a e:Freemason .
e:Eugene a e:Freemason .
e:Mike a e:Freemason .
e:Alan a e:Freemason .
e:Paul a e:Civilian .
e:Marty foaf:knows e:Eugene .
e:Eugene foaf:knows e:Mike .
e:Eugene foaf:knows e:Paul .
e:Paul foaf:knows e:Alan .
## RDF-Turtle End ##
Using Property Path Pattern from SPARQL that has been deprecated
but preserved in Virtuoso
PREFIX e: <http://kingsley.idehen.net/DAV/home/kidehen/Public/Linked%20Data%20Documents/Tutorials/club-member-test.ttl#>
PREFIX dsn: <http://kingsley.idehen.net/DAV/home/kidehen/Public/Linked%20Data%20Documents/Tutorials/club-member-test.>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT *
FROM dsn:ttl
WHERE {
e:Marty foaf:knows{2} ?target .
?target a e:Freemason .
}
Live Links:
Query Solution
Query Definition

Related

SPARQL-query to get data from wikidata not working

I try to get some image links from wikidata by running a SPARQL-query from my local Jena Fuseki instance. I want to merge it with data from my local graph. Unfortunately the query isn't delivering any data but runs and runs instead without any error message.
The sparql-query:
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?image WHERE {
?s foaf:name ?name.
?s owl:sameAs ?wikidata_link.
FILTER regex(str(?wikidata_link), "wikidata").
SERVICE <https://query.wikidata.org/sparql> {
?wikidata_link wdt:P18 ?image.
}
} LIMIT 10
The test data I have in my local graph on the Jena Fuseki server:
#base <http://dmt.de/pages> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
#prefix dbp: <http://dbpedia.org/resource/> .
#prefix wd: <https://www.wikidata.org/entity/> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
<#john-cage>
a foaf:Person ;
foaf:name "John Cage";
owl:sameAs dbp:John_Cage, wd:Q180727.
<#karlheinz-stockhausen>
a foaf:Person ;
foaf:name "Karlheinz Stockhausen";
owl:sameAs dbp:Karlheinz_Stockhausen, wd:Q154556.
<#arnold-schoenberg>
a foaf:Person;
foaf:name "Arnold Schönberg";
owl:sameAs dbp:Arnold_Schoenberg, wd:Q154770.
I tried a similar query for dbpedia-data which run perfectly.
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX dbp: <http://dbpedia.org/resource/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?name ?dbpedia_link ?birthplace WHERE {
?s foaf:name ?name.
?s owl:sameAs ?dbpedia_link.
FILTER regex(str(?dbpedia_link),"dbpedia.org").
SERVICE <https://dbpedia.org/sparql> {
?dbpedia_link dbo:birthPlace ?birthplace.
}
} LIMIT 10
Any Ideas? Thanks in advance!

Get MAX result from COUNT in SPARQL

I have this query:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX curricula: <http://www.semanticweb.org/lsarni/ontologies/curricula#>
SELECT ?topic (COUNT(?x) as ?number_of_courses)
WHERE {
?topic curricula:taughtIn ?x .
}
GROUP BY ?topic
ORDER BY desc(?number_of_courses)
That returns:
Now I want to get the ?topic with the max ?number_of_courses, in this case Engineering
I managed to get the max ?number_of_courses with this query (following this answer):
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX curricula: <http://www.semanticweb.org/lsarni/ontologies/curricula#>
SELECT (MAX(?number_of_courses) AS ?maxc)
WHERE{
{
SELECT ?topic (COUNT(?x) as ?number_of_courses)
WHERE {
?topic curricula:taughtIn ?x .
}
GROUP BY ?topic
}
}
This returns:
But I can't manage to get the ?topic.
How could I fix this?
Update
I tried what I understood from AKSW comment:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX curricula: <http://www.semanticweb.org/lsarni/ontologies/curricula#>
SELECT ?topic
WHERE {
?topic curricula:taughtIn ?x .
{
SELECT (MAX(?number_of_courses) AS ?max)
WHERE {
{
SELECT ?topic (COUNT(?x) as ?number_of_courses)
WHERE {
?topic curricula:taughtIn ?x .
}
GROUP BY ?topic
}
}
}
}
GROUP BY ?topic
HAVING (COUNT(?x) = ?max)
But it returns nothing.
Example
For this minimal example the result should be Topic_2 since it's taughtIn two courses.
#prefix : <http://www.semanticweb.org/lsarni/ontologies/curricula#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#base <http://www.semanticweb.org/lsarni/ontologies/curricula> .
<http://www.semanticweb.org/lsarni/ontologies/curricula> rdf:type owl:Ontology .
#################################################################
# Object Properties
#################################################################
### http://www.semanticweb.org/lsarni/ontologies/curricula#taughtIn
:taughtIn rdf:type owl:ObjectProperty ;
rdfs:subPropertyOf owl:topObjectProperty .
### http://www.w3.org/2002/07/owl#topObjectProperty
owl:topObjectProperty rdfs:domain :Topic ;
rdfs:range :Course .
#################################################################
# Classes
#################################################################
### http://www.semanticweb.org/lsarni/ontologies/curricula#Course
:Course rdf:type owl:Class ;
owl:disjointWith :Topic .
### http://www.semanticweb.org/lsarni/ontologies/curricula#Topic
:Topic rdf:type owl:Class .
#################################################################
# Individuals
#################################################################
### http://www.semanticweb.org/lsarni/ontologies/curricula#Course_1
:Course_1 rdf:type owl:NamedIndividual ,
:Course .
### http://www.semanticweb.org/lsarni/ontologies/curricula#Course_2
:Course_2 rdf:type owl:NamedIndividual ,
:Course .
### http://www.semanticweb.org/lsarni/ontologies/curricula#Topic_1
:Topic_1 rdf:type owl:NamedIndividual ,
:Topic ;
:taughtIn :Course_1 .
### http://www.semanticweb.org/lsarni/ontologies/curricula#Topic_2
:Topic_2 rdf:type owl:NamedIndividual ,
:Topic ;
:taughtIn :Course_1 ,
:Course_2 .
### Generated by the OWL API (version 4.2.8.20170104-2310) https://github.com/owlcs/owlapi

Error handling of SPARQL query with given RDF graph

I have the following RDF graph with prefixes
PREFIX r: <http://dbpedia.org/resources/>
PREFIX o: <http://dbpedia.org/ontology/>
And the query
PREFIX r: <http://dbpedia.org/resources/>
PREFIX o: <http://dbpedia.org/ontology/>
SELECT ?s ?author
WHERE {
?s o:type o:Book .
?s o:author ?author .
?author ?incategory r:Category:American_atheists.
}
I am now wondering what the output would look like. I have tried using https://dbpedia.org/sparql but this results in a parsing error.
Is this a proper query anyway ?
The graph has the prefix r for Book and the query has o:Book in the triple.
The parsing error is due to the colon after r:Category. Colon in abbreviated IRIs can only be used as part of the prefix. This query should work:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX r: <http://dbpedia.org/resource/>
PREFIX o: <http://dbpedia.org/ontology/>
SELECT ?s ?author
WHERE {
?s rdf:type o:Book .
?s o:author ?author .
?author ?incategory <http://dbpedia.org/resource/Category:American_atheists> .
}
Or, if you want a more concise WHERE clause:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX r: <http://dbpedia.org/resource/>
PREFIX o: <http://dbpedia.org/ontology/>
PREFIX c: <http://dbpedia.org/resource/Category:>
SELECT ?s ?author
WHERE {
?s rdf:type o:Book .
?s o:author ?author .
?author ?incategory c:American_atheists .
}

Federated queries on dbpedia and linkedmdb

I am writing a federated query to get the books based on films in dbpedia and in turn using the film name from dbpedia to retrieve the corresponding imdblink link for the same. I am getting an empty set when I add the service of linkedmdb.
Here is my code
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX movie: <http://data.linkedmdb.org/resource/movie/>
PREFIX dc: <http://purl.org/dc/terms/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dbp: <http://dbpedia.org/property/>
SELECT distinct ?name ?author ?filmname ?imdbID WHERE {
SERVICE <http://dbpedia.org/sparql> {
?book rdf:type dbo:Book .
?book foaf:name ?name .
?book dbp:author ?author .
?author foaf:name ?authname .
?book ^dbo:basedOn ?movie .
?movie a dbo:Film .
?movie foaf:name ?filmname
FILTER (str(?name) IN ("Royal Flash","White Oleander", "Possession: A Romance", "Misery", "Intensity", "The War of The Roses", "Momo", "The Sicilian", "Derailed", "Ragtime"))
}
SERVICE <http://data.linkedmdb.org/sparql> {
?filmname foaf:page ?imdbID .
?filmname dc:title ?title .
FILTER(regex(str(?imdbID), "www.imdb.com" ) )
}
}
I am using the following endpoint http://www.sparql.org/query.html
That does not work because of the ?filename variable
in the first SERVICE clause you get
?movie foaf:name ?filmname, thus, those are string literals
in the second SERVICE clause ?filmname are URIs
It will become easy to see if you run both SPARQL queries separately.
What you would have to do is to match on the title, i.e. change
?filmname dc:title ?title .
to
?filmname dc:title ?filmname .
Note, this might not work because of different types of strings, e.g. with and without language tag etc.
In that case you would have to match on the lexical form again, i.e. use temporary variables ?filmname1 and ?filmname2 and use
FILTER(str(?filmname1) = str(?filmname2))
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
PREFIX movie: <http://data.linkedmdb.org/resource/movie/>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc: <http://purl.org/dc/terms/>
SELECT DISTINCT ?name ?author ?filmname1 ?imdbID
WHERE
{ SERVICE <http://dbpedia.org/sparql>
{ ?book rdf:type dbo:Book ;
foaf:name ?name ;
dbp:author ?author .
?author foaf:name ?authname .
?book ^dbo:basedOn ?movie .
?movie rdf:type dbo:Film ;
foaf:name ?filmname1
FILTER ( str(?name) IN ("Royal Flash", "White Oleander", "Possession: A Romance", "Misery", "Intensity", "The War of The Roses", "Momo", "The Sicilian", "Derailed", "Ragtime") )
}
SERVICE <http://data.linkedmdb.org/sparql>
{ ?filmname foaf:page ?imdbID ;
dc:title ?filmname2
FILTER regex(str(?imdbID), "www.imdb.com")
}
FILTER ( str(?filmname1) = str(?filmname2) )
}

How to query DBpedia SPARQL by resource uri?

I'm querying DBpedia types in SPARQL (http://dbpedia.org/sparql) by resource's label
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
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/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX : <http://dbpedia.org/resource/>
PREFIX ru: <http://ru.dbpedia.org/resource/>
PREFIX dbpedia2: <http://dbpedia.org/property/>
PREFIX dbpedia: <http://dbpedia.org/>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?type ?superType WHERE { {
?res rdfs:label "HarryPotter"#en.
} UNION {
?redir dbo:wikiPageRedirects ?res .
?redir rdfs:label "HarryPotter"#en .
}
?res rdf:type ?type .
OPTIONAL {
?type rdfs:subClassOf ?superType .
}
}
It works fine.
But what if I know the exact resource - http://dbpedia.org/page/Harry_Potter? I tried something like:
?res a :Harry_Potter.
But it does not work.
How to query DBpedia types and supertypes if I know the resource URI? I can't figure out which property or operator I should use (e.g., rdfs:Resource, a, etc., which do not work)
When you write
?res a :Harry_Potter.
It doesn't work, because this means "a resource, which is of type :Harry_Potter". It is equivalent to
?res rdf:type :Harry_Potter.
:Harry_Potter identifies a resource and not the type, thus it should be used in place of ?res.
Also I think you mean Harry_Potter_(character), because that is the actual identifier and not redirect.
You query would be as simple as
SELECT ?type ?superType WHERE
{
# give me ?type of the resource
<http://dbpedia.org/resource/Harry_Potter_(character)> rdf:type ?type .
# give me ?superTypes of ?type
OPTIONAL {
?type rdfs:subClassOf ?superType .
}
}
You can just put the URI as the subject in there WHERE conditions.
SELECT ?title, ?releaseDate
WHERE {
<http://dbpedia.org/resource/Super_Mario_Bros._3> dbp:title ?title .
<http://dbpedia.org/resource/Super_Mario_Bros._3> dbo:releaseDate ?releaseDate .
}