SPARQL§

author:Pierre-Antoine Champin

Contrat Creative Commons

Introduction§

Objectifs§

  • Vous donner des bases pour écrire des requêtes SPARQL.

  • Bonus: lire/écrire du Turtle (très proche de SPARQL).

  • Ce n’est qu’une introduction ; pour en savoir plus :

    http://www.w3.org/TR/sparql11-overview/

Requête simple§

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

SELECT ?n1 ?n2
WHERE {
    ?p1 a <http://xmlns.com/foaf/0.1/Person> .
        foaf:name ?n1 ;
        foaf:knows ?p2 .
    ?p2 a foaf:Person ;
        foaf:name ?n2 .
}

digraph simpleSelectQuery {
graph [ rankdir="LR" ]

Person [ label="foaf:Person" ]
p1 [ label="?p1" ]
n1 [ label="?n1" style=filled, fillcolor=gray ]
p2 [ label="?p2" ]
n2 [ label="?n2" style=filled, fillcolor=gray ]

p1 -> Person [ label="rdf:type" ]
p1 -> n1 [ label="foaf:name" ]
p1 -> p2 [ label="foaf:knows" ]
p2 -> Person [ label="rdf:type" ]
p2 -> n2 [ label="foaf:name" ]
}

Description du graphe§

Préfixes§

Rappel : les préfixes servent à abréger les IRIs.

SPARQL :

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX : <http://example.com/>

Turtle :

@prefix foaf: <http://xmlns.com/foaf/0.1/> . # ⚠ point final
@prefix : <http://example.com> .   # après chaque déclaration

Termes§

IRI en extension (relatif ou absolu) :

<http://xmlns.org/foaf/0.1/Person>
<../other-file.rdf>
<#something>
<>

IRI abrégé :

foaf:Person
:something

Termes (suite)§

Litéral :

"Bonjour"
"Hello"@en          # avec tag de langue
"123"^^xsd:integer  # typé

42                  # equiv. "42"^^xsd:integer
1.5                 # equiv. "1.5"^^xsd:decimal
314e-2              # equiv. "314e-2"^^xsd:double
true                # equiv. "true"^^xsd:boolean

Nœud muet :

_:toto
[]       # voir ci-après

Termes (suite)§

Variable (SPARQL seulement) :

?foo
$foo

NB: pas de distinction entre ? et $.

Triplets§

  • 3 termes (sujet, prédicat, objet) séparés par des espaces et suivis d’un point "." :
?p1 foaf:name "Pierre-Antoine Champin" .
  • cas particulier : le mot clé "a" en position de prédicat est un raccourci pour <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> :
?p1 a foaf:Person .
  • le retour à la ligne vaut pour une espace ; la structure est donnée par la ponctuation.

Factorisation§

  • On peut « factoriser » plusieurs triplets ayant le même sujet en séparant les couples <prédicat, objet> par un point-virgule ";" :

    <#pa> a foaf:Person ;
          foaf:givenName "Pierre-Anntoine" ;
          foaf:surname "Champin" .
    
  • On peut « factoriser » plusieurs triplets ayant le même sujet et le même prédicat en séparant les objets par une virgule "," :

    <#pa> foaf:phone <tel:+33-472-44-82-40>, <tel:+33-472-69-21-73>.
    
  • On peut bien sûr combiner les deux types de factorisation.

  • On n’est jamais obligé de factoriser, on peut aussi répéter les termes.

Nœud muet§

Lorsqu’un nœud muet n’a qu’un seul arc entrant, au lieu de lui inventer un identifiant local :

<#pa> foaf:know _:quelqun .
_:quelqun a foaf:Person ; foaf:name ?n .

on peut utiliser la notation [] :

<#pa> foaf:knows [
    a foaf:Person ;
    foaf:name ?n
] .

digraph bracketBlankNode {
graph [ rankdir=LR ]

pa [ label="<#pa>" ]
bn [ label="" ]
Person [ label="foaf:Person" ]
n [ label="?n" ]
pa -> bn [ label="foaf:knows" ]
bn -> Person [ label="rdf:type" ]
bn -> n [ label="foaf:name"]
}

Sous-graphe optionel§

En SPARQL, on peut accepter qu’une partie du graphe ne soit pas satisfaite :

?p1 a foaf:Person ; foaf:name ?n .
OPTIONAL { ?p1 foaf:phone ?tel }

Filtres§

En SPARQL, on peut ajouter des contraintes sur les valeurs d’un graphe, avec la clause FILTER.

?p foaf:age ?a .
FILTER (?a >= 18)

On peut combiner des conditions avec les opérateurs logiques « et » (&&), « ou » (||) et « non » (!).

FILTER ( 20 <= ?a  &&  ?a < 30 )

Opérations utiles pour les filtres§

  • comparaisons : =, !=, <, >, <=, >=
  • opérateurs arithmétiques : +, -, *, /
  • nature d’un nœud : isIRI, isBLANK, isLITERAL, isNUMERIC
  • vérifier qu’une variable (utilisée avec OPTIONAL) a bien une valeur : Bound
  • recherche de texte : REGEX(<variable>, <texte>)

Requête SELECT§

Présentation§

  • Similaire au SELECT de SQL :

    projection sur un sous-ensemble des variables du graphe

  • Résultat : tableau

    • une colonne par variable sélectionnée
    • une ligne par résultat
  • Structure :

    SELECT <variables> WHERE { <graphe> }

DISTINCT§

SELECT DISTINCT ?sn
WHERE { <#pa> foaf:knows ?p. ?p foaf:surname ?sn. }

digraph exempleDistinct {
graph [ rankdir=LR ]

pa [ label="<#pa>" ]
john [ label="" ]
jane [ label="" ]
doe [ shape=rectangle, label="Doe" ]
john_name [ shape=rectangle, label="John" ]
jane_name [ shape=rectangle, label="Jane" ]

pa -> john [ label="foaf:knows" ]
pa -> jane [ label="foaf:knows" ]
john -> john_name [ label="foaf:givenName" ]
john -> doe [ label="foaf:surname" ]
jane -> doe [ label="foaf:surname" ]
jane -> jane_name [ label="foaf:givenName" ]
}

LIMIT et OFFSET§

Pour obtenir les 10 premiers résultats :

SELECT ?p
WHERE { <#pa> foaf:knows ?p. }
LIMIT 10

Pour obtenir les 5 résultats suivants :

SELECT ?p
WHERE { <#pa> foaf:knows ?p. }
LIMIT 5 OFFSET 10

ORDER BY§

SELECT ?p ?n
WHERE { <#pa> foaf:knows [ foaf:givenName ?p ; foaf:surname ?n ] }
ORDER BY ?n ?p

On peut aussi trier par ordre descendant :

SELECT ?p ?n
WHERE { <#pa> foaf:knows [ foaf:age ?age ] }
ORDER BY DESC(?age)
LIMIT 1

GROUP BY§

Sert à aggréger certaines valeurs avec l’une des fonctions d’aggrégations : Count, Sum, Avg, Min, Max, GroupConcat et Sample.

SELECT ?p1 count(?p2)
WHERE { ?p1 foaf:knows ?p2 }
GROUP BY ?p1

On peut combiner GROUP BY avec ORDER BY et LIMIT (attention à l’ordre) :

SELECT ?p1 count(?p2)
WHERE { ?p1 foaf:knows ?p2 }
GROUP BY ?p1
ORDER BY DESC(count(?p2))
LIMIT 3

Autres types de requête§

ASK§

  • Sert à demander si un graphe existe ou non dans la base.

  • Résultat : vrai ou faux

  • Structure :

    ASK { <graphe> }

CONSTRUCT§

  • Sert à construire un graphe à partir des résultat d’un autre

  • Résultat : un graphe RDF

  • Structure :

    CONSTRUCT { <graphe> } WHERE { <graphe> }

  • Peut jouer un rôle similaire à XSL-T pour RDF

SPARQL Update§

Depuis la version 1.1, possibilité de modifier les données.

Quelques requêtes utiles§

Exploration des types de ressources§

SELECT ?type count(?o)
WHERE { ?o a ?type }
GROUP BY ?type
ORDER BY DESC(count(?o))
LIMIT 30

Exploration des propriétés liées à un type§

SELECT DISTINCT ?prop
WHERE { ?o a <http://example.org/UnType> ; ?prop ?val . }
LIMIT 30