Sparql Query to Get All Parent of a Node

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.

  1. I downloaded and set up HyperGraphQL download page
  2. 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 the Class, id, label and subClassOf):

    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")
    }
  3. I started testing some simple query, but constantly getting an empty response; the answer to this issue solved my problem.

  4. 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 the skos:prefLabel also to this entity

  • As already pointed out by UninformedUser
    you have to specify the relation between DOID_11684 and DOID_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



Leave a reply



Submit