SPARQL¶
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 :
Requête simple¶
Considérons les données suivantes:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?n1 ?n2
WHERE {
?p1 a foaf:Person ;
foaf:name ?n1 ;
foaf:knows ?p2 .
?p2 a foaf:Person ;
foaf:name ?n2 .
}
Résultats¶
n1 |
n2 |
---|---|
Alice |
Bob |
Carol |
Dan |
Dr Jekyll |
Dan |
Mr Hide |
Dan |
Description du graphe requête¶
Préfixes¶
Rappel : les préfixes servent à abréger les IRIs.
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX : <http://example.com/>
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 :
"Hello"@en # avec tag de langue
"123"^^xsd:integer # typé
"Bonjour" # equiv. "Bonjour"^^xsd:string
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) :
?x
$y
NB: pas de distinction entre ?
et $
,
donc ?x
et $x
identifient la même variable.
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 uniquement.
Factorisation¶
On peut « factoriser » plusieurs triplets ayant le même sujet en séparant les couples <prédicat, objet> par un point-virgule
";"
:?p a foaf:Person ; foaf:givenName "Pierre-Anntoine" ; foaf:familyName "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
","
:?p 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
] .
Union¶
Pour exprimer un « ou » logique entre plusieurs contraintes,
on place chaque alternative entre accolades,
séparées par le mot-clé UNION
:
<#pa> foaf:knows ?p1 .
{ ?p1 a foaf:Person ; foaf:name ?n }
UNION
{ ?p1 a schema:Person; schema:name ?n }
Sous-graphe optionel¶
On peut accepter qu’une partie du graphe ne soit pas satisfaite :
?p1 a foaf:Person ; foaf:name ?n .
OPTIONAL { ?p1 foaf:img ?img }
OPTIONAL { ?p1 foaf:phone ?tel }
ou
?p1 a foaf:Person ; foaf:name ?n1 .
OPTIONAL { ?p1 foaf:knows ?p2. ?p2 foaf:name ?n2 }
Dans le résultat, les variables des clauses optionnelles peuvent donc ne recevoir aucune valeur (null).
Note
Dans le deuxième exemple (et contrairement au premier), les deux triplets optionnels sont « solidaires », si l’un d’eux est manquant, c’est toute la clause optionnelle qui est considérée comme non satisfaite.
Ainsi, dans le graphe suivant :
le résultat sera : p1=a, n1=“Alice », p2=null, n2=null .
Filtres¶
On peut ajouter des contraintes sur les valeurs des résultats,
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érateurs et fonctions 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>)
Pour plus d’information, consultez la documentation de SPARQL.
Requête fédérée¶
Avec la clause SERVICE
,
il est possible de transmettre une partie de la requête à un autre point d’accès SPARQL.
?p a foaf:Person ; owl:sameAs ?db .
FILTER (regex(str(?db), "dbpedia.org"))
SERVICE <http://dbpedia.org/sparql> {
?db dbo:birthDate ?birth
}
Note
Cette fonctionnalité est souvent désactivé dans les points d’accès SPARQL public, pour des raisons de sécurité.
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/expression> WHERE { <graphe> }
Expression¶
Les résultats du SELECT peuvent être des expressions complexes, calculées à partir des variables de la clause WHERE.
SELECT ?p (concat(?gn, " ", ?fn) as ?name)
WHERE { ?p foaf:givenName ?gn ; foaf:familyName ?fn . }
DISTINCT¶
SELECT DISTINCT ?sn
WHERE { <#pa> foaf:knows ?p. ?p foaf:familyName ?sn. }
Sans le DISTINCT
, la requête renverra deux fois le résultat sn="Doe"
.
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:familyName ?n ] }
ORDER BY ?n ?p
On peut aussi trier par ordre descendant :
SELECT ?name ?age
WHERE { <#pa> foaf:knows [ foaf:name ?name ; foaf:age ?age ] }
ORDER BY DESC(?age)
LIMIT 1
Note
l’utilisation du tri et de LIMIT 1
permet ici de n’obtenir
que la personne la plus vieille que connaît <#pa>
.
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) as ?cp2)
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) as ?cp2)
WHERE { ?p1 foaf:knows ?p2 }
GROUP BY ?p1
ORDER BY DESC(?cp2)
LIMIT 3
Sous-requêtes¶
Il est possible d’inclure, dans une clause WHERE
,
une requête SELECT
entre accolades.
Par exemple, la requête suivante donne, pour chaque personne, son écart par rapport à l’age moyen.
SELECT ?p ((?age - ?ageMoyen) as ?ecart)
WHERE {
?p a foaf:Person ; foaf:age ?age .
{
SELECT (avg(?age2) as ?ageMoyen) {
?p2 a foaf:Person ; foaf:age ?age2.
}
}
}
Quelques requêtes utiles¶
Ces requêtes permettent de découvrir le vocabulaire utilisé par une source de données.
Exploration des types de ressources¶
SELECT ?type
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
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
Exemple¶
CONSTRUCT {
?p1 ex:hasMutualFriendWith ?p3 ;
foaf:name ?n1 .
?p3 foaf:name ?n3 .
} WHERE {
?p1 foaf:knows ?p2 .
?p3 foaf:knows ?p2 .
FILTER(?p1 != ?p3)
OPTIONAL { ?p1 foaf:name ?n1 }
OPTIONAL { ?p3 foaf:name ?n3 }
}
construit un graphe contenant des arcs ex:hasMutualFriendWith
entre les personnes qui partagent au moins un ami,
et copie également les arcs foaf:name
concernant ces personnes, le cas échéant.
Résultat de l’exemple¶
En appliquant l’exemple de CONSTRUCT
ci-dessus
au graphe donné en exemple en début de chapitre, on obtient :
SPARQL Update¶
Depuis la version 1.1, possibilité de modifier les données.