Reputation: 93
I'm a naive user trying to replicate a query that results in the following type of string:
derives_from some (epithelial cell and (part_of some (uterine cervix and (part_of some (Homo sapiens and (has disease some adenocarcinoma)))))
I'm at a hackathon, we have no ontology/SPARQL expert, and we're just trying to get these related fields out of this ontology and into SOLR. We're desperate!
The webpage this is from http://www.ontobee.org/ontology/CLO?iri=http://purl.obolibrary.org/obo/CLO_000368) helpfully provides all the SPARQL queries that are used on the page. I think this is the relevant query:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
SELECT DISTINCT ?ref ?refp ?label ?o FROM <http://purl.obolibrary.org/obo/merged/CLO> WHERE {
?ref ?refp ?o .
FILTER ( ?refp IN ( owl:equivalentClass, rdfs:subClassOf ) ) .
OPTIONAL { ?ref rdfs:label ?label } .
{
{
SELECT ?s ?o FROM <http://purl.obolibrary.org/obo/merged/CLO> WHERE {
?o ?p ?s .
FILTER ( ?p IN ( rdf:first, rdf:rest, owl:intersectionOf, owl:unionOf, owl:someValuesFrom, owl:hasValue, owl:allValuesFrom, owl:complementOf, owl:inverseOf, owl:onClass, owl:onProperty ) )
}
}
OPTION ( TRANSITIVE, t_in( ?s ), t_out( ?o ), t_step( ?s ) as ?link ).
FILTER ( ?s= <http://purl.obolibrary.org/obo/CLO_0003684> )
}
}
ORDER BY ?label
However, I can't even run that to check, because my SPARQL endpoint doesn't support Virtuoso. http://sparql.bioontology.org So, it spits back an error on OPTION(TRANSITIVE). Can anyone show me the equivalent standard pathway language? There are varying pathway lengths between the target nodes.
Upvotes: 0
Views: 442
Reputation: 22042
Virtuoso's transitivity operator is more powerful than what standard SPARQL provides, so in the general case it will not always be possible to express the same thing in a single standard SPARQL query. However, I believe that in this case it is possible.
The following property path would be the equivalent (disclaimer, I haven't tested this query, but it should give you the general idea):
?o (rdf:first|rdf:rest|owl:intersectionOf|owl:unionOf|owl:someValuesFrom|owl:hasValue|owl:allValuesFrom|owl:complementOf|owl:inverseOf|owl:onClass|owl:onProperty)+ ?s .
The full query would become something like this:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
SELECT DISTINCT ?ref ?refp ?label ?o FROM <http://purl.obolibrary.org/obo/merged/CLO> WHERE {
?ref ?refp ?o .
FILTER ( ?refp IN ( owl:equivalentClass, rdfs:subClassOf ) ) .
OPTIONAL { ?ref rdfs:label ?label } .
{
{
SELECT ?s ?o FROM <http://purl.obolibrary.org/obo/merged/CLO> WHERE {
?o (rdf:first|rdf:rest|owl:intersectionOf|owl:unionOf|owl:someValuesFrom|owl:hasValue|owl:allValuesFrom|owl:complementOf|owl:inverseOf|owl:onClass|owl:onProperty)+ ?s .
}
}
FILTER ( ?s= <http://purl.obolibrary.org/obo/CLO_0003684> )
}
}
ORDER BY ?label
Note, by the way, that the FILTER
condition on your variable ?s
is outside the subselect, which might make this query a bit of a performance hog. Since you are not using ?s
anywhere else in the query, you can simplify this part of the query further, eliminating the FILTER
, like so:
{
{
SELECT ?o FROM <http://purl.obolibrary.org/obo/merged/CLO> WHERE {
?o (rdf:first|rdf:rest|owl:intersectionOf|owl:unionOf|owl:someValuesFrom|owl:hasValue|owl:allValuesFrom|owl:complementOf|owl:inverseOf|owl:onClass|owl:onProperty)+ <http://purl.obolibrary.org/obo/CLO_0003684> .
}
}
}
Upvotes: 2