SPARQL to get all parents of all nodes
Your first query isn't legal. You can check at sparql.org's query validator. While you can order by count(?mid), you can't bind the value to a variable and order by it in the same clause. That would give you:
select (group_concat(distinct ?midlab ; separator = "|") AS ?lineage)
where
{
bto:BTO_0000207 rdfs:subClassOf* ?mid .
?mid rdfs:subClassOf* ?class .
?mid rdfs:label ?midlab .
}
group by ?lineage
order by count(?mid)
Now, that's legal, but it doesn't make quite as much sense. group_concat requires that you have some groups, and that you'll do a concatenation for the values within each group. In the absence of a group by clause, you get an implicit group, so the group_concat without a group by is OK. But you've got a group by ?lineage that doesn't make a whole lot of sense, because ?lineage already only has one value per group (since it's already an aggregate). Better would be to group by ?s, as in the following. This seems more correct, and might not time out:
select ?s (group_concat(distinct ?midlab ; separator = "|") AS ?lineage)
where
{
?s rdfs:subClassOf* ?mid .
?mid rdfs:subClassOf* ?class .
?mid rdfs:label ?midlab .
}
group by ?s
order by count(?mid)
SPARQL query to get all parent of a node
Your data can be represented in RDF as data.n3
:
@prefix : <http://example.org/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
:Network rdfs:subClassOf :Main .
:ATM rdfs:subClassOf :Network .
:ARPANET rdfs:subClassOf :Network .
:Software rdfs:subClassOf :Main .
:Linux rdfs:subClassOf :Software .
:Windows rdfs:subClassOf :Software .
:XP rdfs:subClassOf :Windows .
:Win7 rdfs:subClassOf :Windows .
:Win8 rdfs:subClassOf :Windows .
From here, you just want a SPARQL query that finds all the things connected to a particular class by a path (including the empty path) of rdfs:subClassOf
properties.
prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?superclass where {
:Win7 rdfs:subClassOf* ?superclass
}
--------------
| superclass |
==============
| :Win7 |
| :Windows |
| :Software |
| :Main |
--------------
The results in that query aren't necessarily ordered by their position in the path (though in this case they happen to be). If you do need them in order, you can do this (which is based on this answer about computing the position of elements in an RDF list):
prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?class where {
:Win7 rdfs:subClassOf* ?mid .
?mid rdfs:subClassOf* ?class .
}
group by ?class
order by count(?mid)
This finds each ancestor ?class
of :Win7
as well as each ?mid
intermediate ancestor. For ancestor ?class
, the distance is computed as the number of intermediate relations in between (count(?mid)
). It orders the results based that distance, so :Win7
is the closest ancestor, :Windows
after that, and so on.
You can even do some of the fancy formatting you want like this:
prefix : <http://example.org/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select (group_concat( ?name ; separator="--" ) as ?path) where {
{
select ?name where {
:Win7 rdfs:subClassOf* ?mid .
?mid rdfs:subClassOf* ?class .
bind( strAfter( str(?class), "http://example.org/") as ?name )
}
group by ?class ?name
order by count(?mid)
}
}
-----------------------------------
| path |
===================================
| "Win7--Windows--Software--Main" |
-----------------------------------
It might be possible to do some fancier string processing and to get the multiline string. You might look at the latter part of this answer where there is some fancy formatting for a nicely aligned matrix for ideas.
Extract all parents of a given node
Thanks to @AKSW I found a decent solution using HyperGraphQL (a GraphQL interface for querying and serving linked data on the Web).
I'll leave the detailed answer here, it may help someone.
- I downloaded and set up HyperGraphQL download page
Linked it to EBI Sparql endpoint as described in this tutorial
The
config.json
file I used:{
"name": "ebi-hgql",
"schema": "ebischema.graphql",
"server": {
"port": 8081,
"graphql": "/graphql",
"graphiql": "/graphiql"
},
"services": [
{
"id": "ebi-sparql",
"type": "SPARQLEndpointService",
"url": "http://www.ebi.ac.uk/rdf/services/sparql",
"graph": "http://rdf.ebi.ac.uk/dataset/go",
"user": "",
"password": ""
}
]
}Here's how my
ebischema.graphql
file looks like (Since I needed only theClass
,id
,label
andsubClassOf
):type __Context {
Class: _@href(iri: "http://www.w3.org/2002/07/owl#Class")
id: _@href(iri: "http://www.geneontology.org/formats/oboInOwl#id")
label: _@href(iri: "http://www.w3.org/2000/01/rdf-schema#label")
subClassOf: _@href(iri: "http://www.w3.org/2000/01/rdf-schema#subClassOf")
}
type Class @service(id:"ebi-sparql") {
id: [String] @service(id:"ebi-sparql")
label: [String] @service(id:"ebi-sparql")
subClassOf: [Class] @service(id:"ebi-sparql")
}I started testing some simple query, but constantly getting an empty response; the answer to this issue solved my problem.
Finally I constructed the query to get the tree
Using this query:
{
Class_GET_BY_ID(uris:[
"http://purl.obolibrary.org/obo/GO_0032259",
"http://purl.obolibrary.org/obo/GO_0007267"]) {
id
label
subClassOf {
id
label
subClassOf {
id
label
}
}
}
}I got some interesting results:
{
"extensions": {},
"data": {
"@context": {
"_type": "@type",
"_id": "@id",
"id": "http://www.geneontology.org/formats/oboInOwl#id",
"label": "http://www.w3.org/2000/01/rdf-schema#label",
"Class_GET_BY_ID": "http://hypergraphql.org/query/Class_GET_BY_ID",
"subClassOf": "http://www.w3.org/2000/01/rdf-schema#subClassOf"
},
"Class_GET_BY_ID": [
{
"id": [
"GO:0032259"
],
"label": [
"methylation"
],
"subClassOf": [
{
"id": [
"GO:0008152"
],
"label": [
"metabolic process"
],
"subClassOf": [
{
"id": [
"GO:0008150"
],
"label": [
"biological_process"
]
}
]
}
]
},
{
"id": [
"GO:0007267"
],
"label": [
"cell-cell signaling"
],
"subClassOf": [
{
"id": [
"GO:0007154"
],
"label": [
"cell communication"
],
"subClassOf": [
{
"id": [
"GO:0009987"
],
"label": [
"cellular process"
]
}
]
},
{
"id": [
"GO:0023052"
],
"label": [
"signaling"
],
"subClassOf": [
{
"id": [
"GO:0008150"
],
"label": [
"biological_process"
]
}
]
}
]
}
]
},
"errors": []
}
EDIT
This was exactly what I wanted, but I noticed that I can't add another sublevel like this:
{
Class_GET_BY_ID(uris:[
"http://purl.obolibrary.org/obo/GO_0032259",
"http://purl.obolibrary.org/obo/GO_0007267"]) {
id
label
subClassOf {
id
label
subClassOf {
id
label
subClassOf { # <--- 4th sublevel
id
label
}
}
}
}
}
I created a new question: Endpoint returned Content-Type: text/html which is not recognized for SELECT queries
Extract all the child nodes for a parent node from turtle file using SPARQL
here we have some issues
- The .ttl file you posted is not correct. There is an error on the definition of the 1st entity which is missing of the
.
at the end. So you have to update the definition from:
<http://purl.obolibrary.org/obo/DOID_8923>
a skos:Concept ;
skos:altLabel "malignant scalp melanoma"@en , "malignant lip melanoma"@en , "malignant melanoma of skin of upper limb"@en , "cutaneous melanoma"@en , "malignant melanoma of ear and/or external auricular canal"@en , "malignant trunk melanoma"@en , "malignant melanoma of skin of trunk except scrotum"@en , "malignant lower limb melanoma"@en , "malignant melanoma of skin of lower limb"@en , "malignant upper limb melanoma"@en , "malignant ear melanoma"@en , "malignant neck melanoma"@en ;
skos:broader <http://purl.obolibrary.org/obo/DOID_4159> ;
skos:definition "A skin cancer that has_material_basis_in melanocytes." ;
skos:inScheme <https://localhost:8443/ontology/Applicanttest/APPLICANTTEST> ;
To:
<http://purl.obolibrary.org/obo/DOID_8923>
a skos:Concept ;
skos:altLabel "malignant scalp melanoma"@en , "malignant lip melanoma"@en , "malignant melanoma of skin of upper limb"@en , "cutaneous melanoma"@en , "malignant melanoma of ear and/or external auricular canal"@en , "malignant trunk melanoma"@en , "malignant melanoma of skin of trunk except scrotum"@en , "malignant lower limb melanoma"@en , "malignant melanoma of skin of lower limb"@en , "malignant upper limb melanoma"@en , "malignant ear melanoma"@en , "malignant neck melanoma"@en ;
skos:broader <http://purl.obolibrary.org/obo/DOID_4159> ;
skos:definition "A skin cancer that has_material_basis_in melanocytes." ;
skos:inScheme <https://localhost:8443/ontology/Applicanttest/APPLICANTTEST> .
The .
at the end, it means that the definition of your entity is complete. While the ;
is used when you need to add other relationships.
The record DOID_8923 has no
skos:prefLabel
so, you are not able to retrieve the prefLabel from DOID_8923. You need to add theskos:prefLabel
also to this entityAs already pointed out by UninformedUser
you have to specify the relation betweenDOID_11684
andDOID_4159
also in your schema
Here you can find your .ttl
file updated and the transitive SPARQL query
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
<http://purl.obolibrary.org/obo/DOID_8923>
a skos:Concept ;
skos:altLabel "malignant scalp melanoma"@en , "malignant lip melanoma"@en , "malignant melanoma of skin of upper limb"@en , "cutaneous melanoma"@en , "malignant melanoma of ear and/or external auricular canal"@en , "malignant trunk melanoma"@en , "malignant melanoma of skin of trunk except scrotum"@en , "malignant lower limb melanoma"@en , "malignant melanoma of skin of lower limb"@en , "malignant upper limb melanoma"@en , "malignant ear melanoma"@en , "malignant neck melanoma"@en ;
skos:broader <http://purl.obolibrary.org/obo/DOID_4159> ;
skos:definition "A skin cancer that has_material_basis_in melanocytes." ;
skos:inScheme <https://localhost:8443/ontology/Applicanttest/APPLICANTTEST> .
<http://purl.obolibrary.org/obo/DOID_3451>
a skos:Concept ;
skos:altLabel "carcinoma of skin"@en ;
skos:broader <http://purl.obolibrary.org/obo/DOID_4159> ;
skos:definition "A skin cancer that is located_in tissues of the skin and develops from epithelial cells." ;
skos:inScheme <https://localhost:8443/ontology/Applicanttest/APPLICANTTEST> ;
skos:prefLabel "skin carcinoma"@en .
<http://purl.obolibrary.org/obo/DOID_6944>
a skos:Concept ;
skos:altLabel "Seborrheic Keratosis of Vulva"@en ;
skos:broader <http://purl.obolibrary.org/obo/DOID_6498> , <http://purl.obolibrary.org/obo/DOID_4159> ;
skos:inScheme <https://localhost:8443/ontology/Applicanttest/APPLICANTTEST> ;
skos:prefLabel "vulvar seborrheic keratosis"@en .
<http://purl.obolibrary.org/obo/DOID_4159>
a skos:Concept ;
skos:altLabel "malignant neoplasm of skin"@en , "CA - skin cancer"@en , "melanoma and Non-melanoma skin cancer"@en ;
skos:broader <http://purl.obolibrary.org/obo/DOID_37> ;
skos:definition "An integumentary system cancer located_in the skin that is the uncontrolled growth of abnormal skin cells." ;
skos:inScheme <https://localhost:8443/ontology/Applicanttest/APPLICANTTEST> ;
skos:prefLabel "skin cancer"@en .
<http://purl.obolibrary.org/obo/DOID_11684>
a skos:Concept ;
skos:broader <http://purl.obolibrary.org/obo/DOID_6498> ;
skos:inScheme <https://localhost:8443/ontology/Applicanttest/APPLICANTTEST> ;
skos:prefLabel "melanoacanthoma"@en .
SPARQL
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix skos: <http://www.w3.org/2004/02/skos/core#>
SELECT *
WHERE {?s skos:broader* <http://purl.obolibrary.org/obo/DOID_4159>;
skos:prefLabel ?prefLabel
}
s prefLabel
<http://purl.obolibrary.org/obo/DOID_4159> skin cancer
<http://purl.obolibrary.org/obo/DOID_3451> skin carcinoma
<http://purl.obolibrary.org/obo/DOID_6944> vulvar seborrheic keratosis
Sparql query to get only top-most elements matching criteria
SELECT DISTINCT ?s WHERE {
?s <http://looneytunes-graph.com/color> "yellow"^^xsd:string .
FILTER NOT EXISTS {
?s hasParent+ [<http://looneytunes-graph.com/color> "yellow"^^xsd:string] .
}
}
With this query you are filtering out the nodes having (a parent node having a parent node having...) a yellow parent node.
How do I recursively follow blank nodes to get all triples about an object?
@UninformedUser provided a solution in a comment. Though the OP thought this query using the recursive property path trick wouldn't grab the first level before nesting, it does grab all their desired data.
SELECT ?s ?p ?o
{ ?e :user_id 123 .
?e (<>|!<>)* ?s .
?s ?p ?o
}
Show all paths of a tree in SPARQL
prefix : <http://example.org/random#>
select (?end as ?bottom) (sum(?change) as ?num)
where {
?begin :hasChild* ?midI .
FILTER NOT EXISTS { [] :hasChild ?begin }
?midI :hasChild ?midJ .
?midI a ?iType .
?midJ a ?jType .
BIND(IF(?iType != ?jType, 1, 0) as ?change)
?midJ :hasChild* ?end .
FILTER NOT EXISTS { ?end :hasChild [] }
} group by ?begin ?end order by ?num
answered by @Uninformeduser
Related Topics
PHP "Header (Location)" Inside Iframe, to Load in _Top Location
PHP Variable Variables with Array Key
Phpmailer Attachment, Doing It Without a Physical File
How to Get the Last Dir from a Path in a String
How to Prevent Self Closing Tag in PHP Simplexml
Create Unique Poll/Vote/Survey in PHP
Phpstorm 2020.2 - PHP Built-In Functions Are Not Recognized
Php: Populating an Array with the Names of the Next 12 Months
Ignoring Errors in File_Get_Contents Http Wrapper
How to Insert Multiple Rows in PHP Pdo MySQL
What Is the Fastest Way to Find the Occurrence of a String in Another String
How to Use MySQL Found_Rows() in PHP
How to Update Timezonedb in PHP (Updating Timezones Info)
Php: Change Color of Text Based on $Value