How to return subgraph from rdf graph - sparql

I have an RDF graph G with several classes assuming for simplicity (Person and Parrot).
The class Person is connected to the class Parrot by the property hasAnimal, e.g.:
#PREFIX : <http://example.org/>
:Hugo rdf:type :Person .
:Hugo rdfs:label "Hugo" .
:Hugo :hasAnimal :Birdy.
:Birdy rdf:type :Parrot .
:Birdy rdfs:label :"Birdy" .
:LonleyBrido rdf:type :Parrot .
What is wanted is a subgraph of G that contains all the triples from Person and Parrot that are directly connected with each other, starting from Person. The initial Person does not matter to me, the important part is that only connected triples are extracted i.e. that only persons that do have a parrot or don't get outputted. What I have already tried is the following:
construct {
?person ?p ?o .
?parrot ?p2 ?o2 .
} where {
?person rdf:type :Person .
?person ?p ?o .
?person :hasAnimal ?parrot .
?parrot rdf:type :Parrot .
?parrot ?p2 ?o2 .
}
So the expected output would be:
:Hugo rdf:type :Person .
:Hugo rdfs:label "Hugo" .
:Hugo :hasAnimal :Birdy.
:Birdy rdf:type :Parrot .
:Birdy rdfs:label :"Birdy" .
I am executing this query on a rdflib graph.
Does anyone have a solution to this problem?

The solution is already described above:
import rdflib
from rdflib.namespace import RDF, RDFS
query = """
construct {
?person ?p ?o .
?parrot ?p2 ?o2 .
} where {
?person rdf:type :Person .
?person ?p ?o .
?person :hasAnimal ?parrot .
?parrot rdf:type :Parrot .
?parrot ?p2 ?o2 .
}
"""
g = rdflib.Graph()
g.parse("example.ttl", format="ttl")
g.bind("rdf", RDF)
g.bind("rdfs", RDFS)
EX= rdflib.Namespace("http://example.org/")
g.bind("example", EX)
result = g.query(query)

Related

Get range class of Datatype property

I have the following SPARQL query
SELECT DISTINCT ?p ?class ?type
WHERE {
?resource ?p ?target .
?p rdfs:range ?class .
?class rdf:type ?type .
}
I get results only for the object properties.
If ?class = xsd:float, then rdf:type = rdfs:Datatype, right?
Why I do not receive also results for the type of data properties?

How to extract RDF triples with specific predicates using sparql

I uploaded a set of RDF triples onto a local Virtuoso endpoint.
Of all these triples, I would like to extract only those whose subjects have at least the predicates http://www.w3.org/2000/01/rdf-schema#label and http://www.w3.org/2000/01/rdf-schema#comment.
For example, from these triples:
<http://dbpedia.org/resource/AccessibleComputing> <http://www.w3.org/2000/01/rdf-schema#label> "AccessibleComputing"#en .
<http://dbpedia.org/resource/AfghanistanGeography> <http://www.w3.org/2000/01/rdf-schema#label> "AfghanistanGeography"#en .
<http://dbpedia.org/resource/AfghanistanGeography> <http://www.w3.org/2000/01/rdf-schema#comment> " ... " .
<http://dbpedia.org/resource/Austroasiatic_languages> <http://www.w3.org/2000/01/rdf-schema#comment> " ... " .
<http://dbpedia.org/resource/AccessibleComputing> <http://dbpedia.org/ontology/wikiPageWikiLink> <http://dbpedia.org/resource/Computer_accessibility> .
<http://dbpedia.org/resource/AfghanistanGeography> <http://dbpedia.org/ontology/wikiPageWikiLink> <http://dbpedia.org/resource/Afghanistan_Geography> .
I would like to get:
<http://dbpedia.org/resource/AfghanistanGeography> <http://www.w3.org/2000/01/rdf-schema#label> "AfghanistanGeography"#en .
<http://dbpedia.org/resource/AfghanistanGeography> <http://www.w3.org/2000/01/rdf-schema#comment> " ... " .
<http://dbpedia.org/resource/AfghanistanGeography> <http://dbpedia.org/ontology/wikiPageWikiLink> <http://dbpedia.org/resource/Afghanistan_Geography> .
Is it possible to do this with one (or more) SPARQL query?
Thank you for helping
This can be done with a CONSTRUCT WHERE query:
CONSTRUCT WHERE {
?s rdfs:label ?label.
?s rdfs:comment ?comment.
?s ?p ?o
}
This is a simplified form of CONSTRUCT that can be used when the CONSTRUCT {} part and the WHERE {} part are identical.
One way is to use DESCRIBE, e.g.:
DESCRIBE ?s
WHERE {
?s rdfs:label ?label .
?s rdfs:comment ?comment .
}
or alternatively with CONSTRUCT :
CONSTRUCT { ?subject ?predicate ?object}
WHERE {
?subject ?predicate ?object .
FILTER EXISTS {
?subject rdfs:label ?label .
?subject rdfs:comment ?comment .
}
}

Delete all triples about event time except earliest event time

I have several triples like this
:event1 :hasTimeStamp "2017-06-30T00:01:00Z" .
:event1 :hasTimeStamp "2017-06-30T00:02:00Z" .
:event1 :hasTimeStamp "2017-06-30T00:03:00Z" .
I would like to delete all of the assertions about :event1's timestamp except the earliest.
I know how to select the earliest, insert it into a scratch named graph, delete all :event1 timestamps, and then copy back from the scratch graph.
Is there a way to do the deletion in place, with no utilization of a temporary/scratch graph?
Here's a nested select, where the inner subselect gets the minimum time, which is then be compared with the individual times form the outer select.
Now I just have to wrap that in the delete.
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT *
WHERE
{ ?s rdf:type <http://turbo.org/procStartTimeMeas> ;
<http://purl.obolibrary.org/obo/IAO_0000136> ?something .
?something <http://purl.obolibrary.org/obo/RO_0002223> ?another .
?another rdf:type <http://turbo.org/R2RInstantiation> .
?s <http://purl.obolibrary.org/obo/IAO_0000004> ?o
{ SELECT ?s (MIN(?o) AS ?earliest)
WHERE
{ ?s rdf:type <http://turbo.org/procStartTimeMeas> ;
<http://purl.obolibrary.org/obo/IAO_0000136> ?something .
?something <http://purl.obolibrary.org/obo/RO_0002223> ?another .
?another rdf:type <http://turbo.org/R2RInstantiation> .
?s <http://purl.obolibrary.org/obo/IAO_0000004> ?o
}
GROUP BY ?s
}
FILTER ( ?o != ?earliest )
}
Try this (not in the production environment):
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
DELETE {
?s <http://purl.obolibrary.org/obo/IAO_0000004> ?o2 .
}
WHERE {
?s <http://purl.obolibrary.org/obo/IAO_0000004> ?o2 .
?s rdf:type <http://turbo.org/procStartTimeMeas> .
FILTER EXISTS {
?s <http://purl.obolibrary.org/obo/IAO_0000004> ?o1 .
?s rdf:type <http://turbo.org/procStartTimeMeas> .
FILTER (?o2 > ?o1)
}
}
I'm not sure I understand correctly what these predicates mean.
I suppose <http://purl.obolibrary.org/obo/IAO_0000004> is :hasTimeStamp of the initial example.
In my answer, ?s rdf:type <http://turbo.org/procStartTimeMeas> is the only selection criterion. Please add other criteria.
(An alternative to the nice solution of #StansilavKralin)
I just did it based on the sample data
#prefix : <http://example.org/> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
:event1 :hasTimeStamp "2017-06-30T00:01:00Z"^^xsd:dateTime .
:event1 :hasTimeStamp "2017-06-30T00:02:00Z"^^xsd:dateTime .
:event1 :hasTimeStamp "2017-06-30T00:03:00Z"^^xsd:dateTime .
Not sure whether this is what you want, but at least it's pretty compact and I'm a big fan of MINUS which is at least more human readable (but maybe less performant):
PREFIX : <http://example.org/>
DELETE {
?event :hasTimeStamp ?ts .
}
WHERE
{ ?event :hasTimeStamp ?ts
MINUS
{ { SELECT ?event (MIN(?_ts) AS ?ts)
WHERE
{ ?event :hasTimeStamp ?_ts }
GROUP BY ?event
}
}
}
I think this does what I want, but I'd like to see suggestions from others. I don't want to be reckless with a deletion.
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
DELETE {
?s <http://purl.obolibrary.org/obo/IAO_0000004> ?o .
}
WHERE
{ SELECT *
WHERE
{ ?s rdf:type <http://turbo.org/procStartTimeMeas> ;
<http://purl.obolibrary.org/obo/IAO_0000136> ?something .
?something <http://purl.obolibrary.org/obo/RO_0002223> ?another .
?another rdf:type <http://turbo.org/R2RInstantiation> .
?s <http://purl.obolibrary.org/obo/IAO_0000004> ?o
{ SELECT ?s (MIN(?o) AS ?earliest)
WHERE
{ ?s rdf:type <http://turbo.org/procStartTimeMeas> ;
<http://purl.obolibrary.org/obo/IAO_0000136> ?something .
?something <http://purl.obolibrary.org/obo/RO_0002223> ?another .
?another rdf:type <http://turbo.org/R2RInstantiation> .
?s <http://purl.obolibrary.org/obo/IAO_0000004> ?o
}
GROUP BY ?s
}
FILTER ( ?o != ?earliest )
}
}

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

SPARQL in Protege 4.3

I need to return individuals for my query:
SELECT ?subject ?class
WHERE { ?subject rdfs:subClassOf ?class.
?class rdfs:comment "linear"#en}
But it works only with subclasses. Should I replace rdfs:subClassOf on different operator?
Your query specifically asks for ?subjects that are subclasses of ?class (where ?class has the rdfs:comment "linear"#en). To retrieve instances of type ?class, you'd use
?subject rdf:type ?class
or, since SPARQL allows abbreviating rdf:type by a,
?subject a ?class
If you can't share details about the body of data, you are querying, you might want to get an idea yourself by checking
SELECT ?s ?p ?subject ?class
WHERE
{ ?s ?p ?class .
?subject rdfs:subClassOf ?class .
?class rdfs:comment "linear"#en .
} ORDER BY ?s ?p ?subject ?class
and/or
SELECT ?subject ?class ?p ?o
WHERE
{ ?subject ?p ?o .
?subject rdfs:subClassOf ?class .
?class rdfs:comment "linear"#en .
} ORDER BY ?subject ?class ?p ?o
from where you can expand in the same manner until you get a handle.