Mysql
 sql >> Base de données >  >> RDS >> Mysql

Requête SPARQL pour obtenir tous les parents d'un nœud

Vos données peuvent être représentées en RDF sous la forme 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 .

À partir de là, vous voulez juste une requête SPARQL qui trouve toutes les choses connectées à une classe particulière par un chemin (y compris le chemin vide) de rdfs:subClassOf propriétés.

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      |
--------------

Les résultats de cette requête ne sont pas nécessairement classés par leur position dans le chemin (bien que dans ce cas, ils le soient). Si vous en avez besoin dans l'ordre, vous pouvez le faire (qui est basé sur cette réponse sur le calcul de la position d'éléments dans une liste RDF ):

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)

Ceci trouve chaque ancêtre ?class de :Win7 ainsi que chaque ?mid ancêtre intermédiaire. Pour l'ancêtre ?class , la distance est calculée comme le nombre de relations intermédiaires entre (count(?mid) ). Il ordonne les résultats en fonction de cette distance, donc :Win7 est l'ancêtre le plus proche, :Windows après cela, et ainsi de suite.

Vous pouvez même faire une partie du formatage fantaisiste que vous voulez comme ceci :

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" |
-----------------------------------

Il pourrait être possible de faire un traitement de chaîne plus sophistiqué et d'obtenir la chaîne multiligne. Vous pouvez regarder la dernière partie de cette réponse où il y a une mise en forme sophistiquée pour une matrice bien alignée pour les idées.