SPARQL§

author:Pierre-Antoine Champin
license:Contrat Creative Commons
1

Introduction§

2

Objectifs§

3

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" margin=0 ]

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

4

Exemple de données§

digraph simpleDataset {
graph [ rankdir="LR" margin=0]

Person [ label="foaf:Person" ]
p1 [ label="a" ]
p2 [ label="b" ]
p3 [ label="c" ]
p4 [ label="d" ]
p5 [ label="e" ]

n1 [ label="Alice" shape=box ]
n2 [ label="Bob" shape=box ]
n3 [ label="Carol" shape=box ]
n4 [ label="Dan" shape=box ]
n5 [ label="Dr Jekyll" shape=box ]
n5b [ label="Mr Hyde" shape=box ]

Person -> p1 [ label="rdf:type" dir=back ]
Person -> p2 [ label="rdf:type" dir=back ]
Person -> p3 [ label="rdf:type" dir=back ]
Person -> p4 [ label="rdf:type" dir=back ]
Person -> p5 [ label="rdf:type" dir=back ]
p1 -> n1 [ label="foaf:name" ]
p2 -> n2 [ label="foaf:name" ]
p3 -> n3 [ label="foaf:name" ]
p4 -> n4 [ label="foaf:name" ]
p5 -> n5 [ label="foaf:name" ]
p5 -> n5b [ label="foaf:name" ]

# there seem to be a bug with contraint=false,
# it reverses the direction of the arc in some cases,
# hence the "dir=back" below
p1 -> p2 [ label="foaf:knows" constraint=false dir=back ]
p3 -> p4 [ label="foaf:knows" constraint=false dir=back ]
p5 -> p4 [ label="foaf:knows" constraint=false ]
}

5

Résultats§

n1 n2
Alice Bob
Carol Dan
Dr Jekyll Dan
Mr Hide Dan
6

Description du graphe requête§

7

Préfixes§

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

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

Termes§

IRI en extension (relatif ou absolu) :

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

IRI abrégé :

foaf:Person
:something
9

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
10

Termes (suite)§

Variable (SPARQL seulement) :

?x
$y

NB: pas de distinction entre ? et $, donc ?x et $x identifient la même variable.

11

Triplets§

?p1 foaf:name "Pierre-Antoine Champin" .
?p1 a foaf:Person .
12

Factorisation§

13

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

14

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

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

Opérations utiles pour les filtres§

17

Requête SELECT§

18

Présentation§

19

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

Sans le DISTINCT, la requête renverra deux fois le résultat sn="Doe".

20

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
21

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

22

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
23

Autres types de requête§

24

ASK§

25

CONSTRUCT§

26

Exemple§

CONSTRUCT {
  ?p1 ex:hasMutualFriendWith ?p3 ;
      foaf:name ?n1 .
  ?p3 foaf:name ?n3 .
} WHERE {
  ?p1 foaf:knows ?p2 .
  ?p3 foaf:knows ?p2 .
  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.

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

digraph simpleDataset {
graph [ rankdir="LR" margin=0]

p3 [ label="c" ]
p5 [ label="e" ]

n3 [ label="Carol" shape=box ]
n5 [ label="Dr Jekyll" shape=box ]
n5b [ label="Mr Hyde" shape=box ]

p3 -> n3 [ label="foaf:name" ]
p5 -> n5 [ label="foaf:name" ]
p5 -> n5b [ label="foaf:name" ]

# there seem to be a bug with contraint=false,
# it reverses the direction of the arc in some cases,
# hence the "dir=back" below
p3 -> p5 [ label="ex:hasMutualFriendWith" ]
p5 -> p3 [ label="ex:hasMutualFriendWith" ]
}

28

SPARQL Update§

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

29

Quelques requêtes utiles§

30

Exploration des types de ressources§

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

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

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