« SPARQL Protocol and RDF Query Language/Requêtes de lecture » : différence entre les versions

Contenu supprimé Contenu ajouté
m Robot : Changement de type cosmétique
Relecture
Ligne 1 :
{{ébauche informatique}}
{{Chapitre
| idfaculté = informatique
Ligne 5 ⟶ 4 :
| titre_leçon = SPARQL
| numéro = 5
| niveau = 130
| précédent = [[../Le protocole SPARQL/]]
| suivant = [[../Requêtes d'écriture/]]
}}
 
L'ambition de SPARQL est d'offrir une interopérabilité, non seulement au niveau des services, comme avec les services Web, mais aussi au niveau des données, structurées ou non, qui sont disponible à travers l'Internet. Toutes ces données disponibles en ligne via SPARQL sont ce que l'on nomme le Web des données. Ce chapitre va nous permettre d'apprendre à interroger ce Web des données.
 
== Introduction ==
=== Commentaires ===
On peut écrire des commentaires dans les requêtes SPARQL. Les commentaires commencent par un '#' en début de ligne.
 
{{remarque|contenu=
LesTous les logiciels ne gèrent pas tous les commentaires. Il faut vérifier que cela n'engendre pas d'erreurs avec la base de données que vous utilisez.
}}
 
=== Préfixes ===
Dans le chapitre [[../Modèle de données RDF/]], nous avons vu comment écrire des IRIs relativesrelatifs à l'aide de préfixes.
En SPARQL également, une requête peut contenir des IRIs relatives, les préfixes doivent être déclaré avant d'écrire une requête.
 
En SPARQL également, une requête peut contenir des IRIs relatives,relatifs. lesLes préfixes doivent être déclarédéclarés avant d'écrire une requête.
Par exemple :
 
'''Exemple : déclaration de préfixes'''
<pre>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
Ligne 36 ⟶ 38 :
=== Abréviations ===
==== rdf:type ====
Vous pourrezpouvez rencontrer dans les requêtes SPARQL le mot "a", qui est l’abréviation du prédicat <nowiki><http://www.w3.org/1999/02/22-rdf-syntax-ns#type></nowiki> (ou rdf:type)
 
{{remarque|titre=Utilisation|contenu=
Le prédicat rdf:type sert à sélectionner l'objet en fonction de son type. C'est donc un prédicat qui est souvent utilisé au sein des requêtes, d'où cette abréviation.
}}
{{remarque|titre=Écriture|contenu=
Ligne 45 ⟶ 47 :
}}
==== Sujet ====
De plus, le sujet des triplets est souvent répété dans une requête pour écrire plusieurs conditions sur ce même sujet. ainsiAinsi, le caractère ";" évite de retaper le sujet des triplets suivants.
 
Par exemple :
'''Exemple de triplets sans ";"'''
<pre>
:book1 dc:title "SPARQL Tutorial" .
Ligne 52 ⟶ 55 :
:book1 foaf:homepage <http://example.org/book/sparql> .
</pre>
 
Est équivalent à
'''Les mêmes triplets avec l'utilisation de ";"'''
<pre>
:book1 dc:title "SPARQL Tutorial" ;
Ligne 72 ⟶ 76 :
 
=== Les littéraux ===
Dans le chapitre [[../Modèle de données RDF/]], nous avons vu comment écrire un littéral dans le format RDF/Turtle. Dans une requête en SPARQL qui utilise également des triplets, comme dans le format RDF/Turtle, les objets peuvent également être des littéraux, en ayant la même syntaxe que Turtle.
 
'''Un littéral dans SPARQL s'écrit comme dans le format Turtle'''
Par exemple :
<pre>
...
Ligne 86 ⟶ 90 :
Une variable dans une requête commence par le caractère "?" et ce caractère ne fait pas partie du nom de la variable.
Le nom d'une variable :
* ne doit pas commencer pas par un chiffre
* est sensible à la casse
* ne doit pas contenir d’espace
* doit être signifiant, car il sert de nom de colonne dans le résultat SPARQL 1.0
 
{{remarque|titre=Nom de colonne dans le résultat SPARQL 1.1|contenu=
Ligne 101 ⟶ 105 :
=== Structure d'une requête ===
Une requête SELECT se divise en 5 parties :
# Définition des préfixes si vous utilisez des IRIs relativesrelatifs
# Définition des résultats que vous désirez obtenir en sortie
# Définition des jeux de données sur lesquelles portentporte la requête,. attention,Attention : seulement disponible dans SPARQL 1.1
# Définition des conditions
# Modificateurs de résultats (facultatif)
 
'''Structure d'une requête SELECT'''
<pre>
# Déclaration des préfixes si ils’il y a utilisation d'IRI relativesrelatifs
PREFIX foo: <...> #Pas d’espace entre Le nom du préfixe et Les deux points
PREFIX ...
Ligne 135 ⟶ 140 :
=== Définir le tableau de résultats ===
 
Nous avons vu dans le protocole SPARQL que les résultats prennent la forme d'un tableau. C'est dans la clause SELECT que les colonnes sont définitdéfinies en alignant les variables qui sont présentes dans la clause WHERE.
Par exemple "'''SELECT ?name ?adress'''" affichera les lignes avec 2 champs : le nom et l'adresse.
 
Vous pouvez aussi écrire :
* "''' SELECT <big>*</big>''' " : permet d'afficher dans les résultats toutes les variables présentes dans la clause WHERE.
* "SELECT '''DISTINCT''' ?country" : permet de ne pas afficher les lignes qui ont un résultat identique.
* dans SPARQL 1.1, "SELECT ?country (100 * ?rate '''AS''' ?percent)" permettra de faire des calculs et renommer les champs, etc. (comme on peut le faire dans SQL)
 
=== Modifier les résultats ===
Pour le moment, on expliquera uniquement l'utilisation dudes motmots-cléclés ORDER BY, LIMIT et OFFSET.
 
==== ORDER BY ====
Ligne 155 ⟶ 160 :
}}
 
Vous constatez qu'en effet, c'est ordonné parselon l'ordre dedes nomnoms, mais vous pouvez également spécifier plusieurs colonnes pour l'ordonnancement du résultat. Par exemple par nom puis par prénom:
{{exemple|titre=Exemple avec plusieurs colonnes|contenu=<pre>SELECT ?familyName ?givenName
WHERE {
Ligne 163 ⟶ 168 :
ORDER BY ?familyName ?givenName</pre>}}
 
Si vous voulez trier une colonne par ordre inverse, il vous suffit d'ajouter le mot-clef DESC devant le nom de la colonne concernée entre parenthèseparenthèses. Par exemple la même requête qu'au dessus avec les noms triés par ordre inverse :
{{exemple|titre=Exemple avec les noms triés par ordre inverse|contenu=<pre>SELECT ?familyName ?givenName
WHERE {
Ligne 171 ⟶ 176 :
ORDER BY DESC(?familyName) ?givenName </pre>}}
 
{{non}} ORDER BY permet de trier selon les colonnes récupérées uniquement. Ainsi, ainsi la requête suivante n'est pas conforme, étant donné que la colonne "givenName" ne fait pas partie des colonnes rapatriées (dans la clause SELECT).
{{exemple|titre=Requête non conforme car ?givenName n'est pas dans la clause SELECT|contenu=
<pre>SELECT ?familyName
Ligne 186 ⟶ 191 :
}}
{{remarque|titre=Utilisation|contenu=
N'hésitez pas à l'utiliser, car dans beaucoup de cas cela vous permettra d'obtenir des temps de réponsesréponse plus faiblefaibles de votre serveur.
}}
==== OFFSET ====
OFFSET permet de n'afficher le résultat qu'à partir de la ligne indiquée.
{{exemple|titre=Exemple de requête qui ne donne le résultat qu'à partir de la cinquième ligne|contenu=
<pre>SELECT * WHERE {?x ?y ?z . } OFFSET 5 </pre>
}}
 
On peut donc indiquer en même temps une LIMIT et un OFFSET.
{{exemple|titre=Exemple qui n'affiche que 10 lignes dude résultat à partir de la ligne 5|contenu=
<pre>SELECT *
WHERE {?x ?y ?z . }
Ligne 201 ⟶ 206 :
LIMIT 10</pre>
}}
On a maintenant tout ce qu'il nous faut pour naviguer de page en page dans les résultats d'une requêtesrequête.
 
=== Définir les conditions ===
La plupart des requêtes SPARQL contiennent un ensemble de triplets appelé '''un masque de graphe'''.
 
Ce masque de graphe est composé d'un ensemble de triplets RDF, saufà ceci près que chaque sujet, prédicat et objet peut être une variable. Chaque triplet devient alors une condition pour notre requête.
 
Ce masque de graphe est comparé à des données RDF. Il y a alors deux réponses possibles :
Ligne 212 ⟶ 217 :
* Ce masque de graphe peut recouvrir un ou plusieurs sous-graphe des données RDF. Le résultat est alors équivalent à tous les sous-graphes ainsi découvert à l'aide de ce masque.
 
==== Écrire une simple requête simple ====
 
L'exemple ci-dessous montre une requête SPARQL pour trouver le titre d'un livre à partir du graphe des données RDF suivant, décrit au format Turtle. La requête se compose de deux parties :
#la clause SELECT identifie les variables à faire apparaître dans la réponse de cette requête,
#et la clause WHERE fournit le masque du graphe à appliquer sur le graphe des données RDF pour chercher cette réponse.
 
Le masque du graphe, dans cet exemple, est constitué d'un triplet avec une seule variable ''"?Titre''" à l'endroit du triplet où l'objet est attendu.
 
Dans le graphe RDF/Turtle :
<pre><http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> "Tutoriel SPARQL»".</pre>
 
On applique la requête SPARQL :
Ligne 232 ⟶ 237 :
}</pre>
 
Cette requête, sur les données ci-dessus, a une seule solution.

Résultat de la requête :
{| class="wikitable"
! scope=col | titre
Ligne 239 ⟶ 246 :
|}
==== Obtenir plusieurs réponses ====
Le résultat d'une requête est un tableau où chaque ligne représente une solution différente, qui correspond à un sous-graphe trouvé à l'aide du masque de la requête. Il peut y avoir zéro, une ou plusieurs solutions à une requête.
 
Chaque ligne contient la liste des variables décritindiquées dans la clause SELECT de la requête. Pour chaque solution, il existe une ligne dans la solution et chaque ligne affichera la valeur qu'a du prendre chaque variable de la clause SelectSELECT pour trouver cette solution.
 
Dans le graphe RDF/Turtle :
Ligne 289 ⟶ 296 :
}}
 
==== Littéral avec une balise de langue ====
 
LaPrécédée du symbole @, la balise de langue, qui suit certainun littéral précédée du symbole @, permet de faire cohabiter dans une même base de données plusieurs langues et permet d'obtenir toutes les langues disponibles à travers une simple requête.
 
Cependant, quantquand on compare un littéral, il est alors indispensable de ne pas oubliéoublier la balise de langue sous peine de n'obtenir aucune solution.
 
Ainsi, la requête :
<pre>SELECT ?v WHERE { ?v ?p "cat" }</pre>
 
ne donne aucune réponse, car elle ne précise pas la même balise de la langue contenucontenue dans les données interrogées.
{| class="wikitable"
! scope=col | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;v&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Ligne 314 ⟶ 321 :
 
==== Littéral avec un type numérique ====
Les entiers, dans une requête SPARQL, sont implicitement de type xsd:integer. <br />
'''Exemple: le littéral 42 est équivalent à l'écriture'''<br />
Par exemple: 42 est équivalent à l'écriture de "42"^^<<nowiki>http://www.w3.org/2001/XMLSchema#integer</nowiki>>.
 
Ainsi, la requête :
Les entiers dans une requête SPARQL sont implicitement de type xsd:integer. <br />
Par exemple: 42 est équivalent à l'écriture de "42"^^<<nowiki>http://www.w3.org/2001/XMLSchema#integer</nowiki>>.
 
Ainsi la requête :
<pre>SELECT ?v WHERE { ?v ?p 42 }</pre>
 
Ligne 332 ⟶ 339 :
La base de données n'a pas besoin de comprendre ce que représente un type pour l'enregistrer ou pour le retrouver. La base de données va simplement comparer la forme lexicale et la référence IRI du type avec les données qu'elle contient.
 
Ainsi, la requête :
<pre>SELECT ?v WHERE { ?v ?p "abc"^^<http://example.org/datatype#specialDatatype> }</pre>
 
Ligne 343 ⟶ 350 :
 
=== Contraintes ===
Un masque de graphe produit une liste de solutionsolutions. On peut, à l'aide du mot clé FILTER, ajouter une contrainte à ce masque. La clause FILTER ajoute une condition qui doit se vérifier pour valider une solution.
 
Nous allons décrire les principales utilisations de la clause FILTER.
 
Nous allons utiliséutiliser le jeu de données RDF/Turtle suivant :
<pre>@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix : <http://example.org/book/> .
Ligne 361 ⟶ 368 :
==== Littéral texte ====
 
regex() est une fonction qui permet d'utiliser une expression régulière pour vérifier une chaîne de caractères sans balise de langue.
 
ParExemple exemple lade requête SPARQL :
<pre>PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
Ligne 377 ⟶ 384 :
|}
 
Pour appliquer cette contrainte à toustout les littéraleslittéral sans se soucier de la balise de langue, on utilise la fonction '''str()'''.
 
Ainsi, la requête SPARQL devient :
<pre>PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
Ligne 395 ⟶ 402 :
|}
 
On peut également appliquer l'option "insensible à la casse" à notre expression régulière, avec le paramètre "i".
 
Par exemple, la requête SPARQL devient :
<pre>PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
Ligne 432 ⟶ 439 :
 
==== Les autres littéraux ====
La clause FILTER peut utiliser de nombreuses fonctions et des opérateurs booléens que nous étudierons dans une futurfuture leçon. Si vous recherchezcherchez une fonction particulière, vous pourrez la trouver, en attendant, dans la documentation de SPARQL ([http://www.w3.org/TR/rdf-sparql-query/#tests la documentation de SPARQL]).
 
=== Jointures ===
Les jointures s'expriment dans une requête SPARQL au sein de la clause WHERE.
==== Jointure basique ====
{{définition|titre=A . B|contenu=
Considérer A et B comme des graphes. "A.B" représente une Jointure.jointure, Il rassemblerassemblant les résultats de A et B en fonction des variables en commun.
}}
Les points qui sépareséparent les triplets dans la clause WHERE représentereprésentent ledes typejointures de jointure à appliquer. Le point étant pour appliquer une jointure basiquebasiques.
 
==== Jointure à gauche ====
{{définition|titre=A OPTIONAL { B }|contenu=
Considérer A et B comme des graphes. "A OPTIONAL { B } " représente une Jointurejointure à gauche. Il rassemble les résultats de A et B en fonction des variables en commun, si possible. Il garde toutes les solutions de A si ils’il y a ou non des résultats dans B.
}}
Un masque peut contenir des clauses optionnelles qui permetpermettent d'ajouter des solutions, sans exclure les solutions qui existent sans nécessairement respecter ces clauses.
 
Un masque peut contenir des clauses optionnelles qui permet d'ajouter des solutions sans exclure les solutions qui existent sans nécessairement respecter ces clauses.
 
Utilisons le graphe RDF/Turtle suivant :
Ligne 481 ⟶ 488 :
|
|}
Pour "Bob", il n'y a pas de valeur pour la variable mbox, car la clause optionnelle n'est pas vérifiée pour "Bob" .
 
On peut mettre plusieurs clauses OPTIONAL dans une requête.
 
Par exemple, avec le graphe RDF/Turtle suivant :
<pre>@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix : <http://example.org/book/> .
Ligne 500 ⟶ 507 :
:book3 ns:price 28 .</pre>
 
Ainsi, la requête :
<pre>PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX ns: <http://example.org/ns#>
Ligne 528 ⟶ 535 :
Considérer A et B comme des graphes. "{ A } UNION { B } " représente une addition. Il rassemble les résultats de A et B sans condition.
}}
Il arrive que les données que l'on désire atteindre, soient enregistrées à des moments différents et donc probablement avec des ontologies différentes, c'est-à-dire dans des graphes de structures différentes.
 
Il arrive que les données que l'on désire atteindre, soient enregistrées à des moments différents et donc probablement avec des ontologies différentes, c'est-à-dire dans des graphes de structures différentes.
 
Il existe leLe mot clé UNION qui permet d'utiliser la même variable dans des masques différents sans s'exclureexclusion mutuellementmutuelle.
 
Par exemple, avec le graphe RDF/Turtle suivant :
<pre>@prefix : <http://example.org/book/> .
@prefix dc10: <http://purl.org/dc/elements/1.0/> .
Ligne 570 ⟶ 577 :
Seulement disponible pour SPARQL 1.1.
{{définition|titre=A MINUS { B }|contenu=
Considérer A et B comme des graphes. "A MINUS { B } " représente une Soustractionsoustraction. Il conserve uniquement les résultats de A qui ne sont pas dans les résultats de B.
}}
 
Ligne 576 ⟶ 583 :
==== Interroger un point d'accès SPARQL ====
 
# Aller sur le site de DBpedia et trouver l’IRI au sein de [http://dbpedia.org/About DBpedia] qui correspond le mieux à la page : http://fr.wikipedia.org/wiki/Doctor_Who
# Dans le formulaire du point d’accès http://dbpedia.org/sparql, écrire une requête pour afficher les prédicats et objets de cet IRI.
# Ecrire une requête pour afficher les sujets et prédicats de cet IRI.
 
{{solution|contenu=
1. En lisant la documentation de DBpedia, vous pouvez comprendre que les IRI des pages WikipediaWikipédia sont les objets du triplet suivant :
 
'''<nowiki><http://dbpedia.org/resource/Doctor_Who> foaf:page <http://en.wikipedia.org/wiki/Doctor_Who></nowiki>'''
 
Vous pouvez remarquer que l'IRI du sujet du triplet ne fait pas référence à une langue. Pourtant, les prédicats et les objets de ce sujet ne font pas référence directement à toutes les pages « Doctor Who » dans tous les Wikiswikis.
 
Seul une petite partie de Wikipedia est utilisé par DBpedia et les pages des langues non anglaises sont très peu exploitées par DBpedia.
{{remarque|titre=Remarque|contenu=
SeulSeule une petite partie de WikipediaWikipédia est utiliséutilisée par DBpedia et les pages des langues non anglaises sont très peu exploitées par DBpedia.
}}
 
La page http://fr.wikipedia.org/wiki/Doctor_Who ne figure pas directement dans DBpedia. La référence (IRI) la plus proche sera donc <http://dbpedia.org/resource/Doctor_Who>
Ligne 604 ⟶ 614 :
==== Faire une requête complexe ====
 
# Avec DBpedia, faire une requête pour trouver les 10dix premiers films français.
# Vous afficherez en résultat pour chaque film : le lien vers la page WikipediaWikipédia du film, la date, le nom et la description.
 
{{solution|contenu=
Ligne 633 ⟶ 643 :
Vous pouvez voir le résultat de cette requête sur la page : http://en.sparql.pro/wiki/First_French_films
 
Vous pouvez trouveztrouver d'autres exemples sur le site avec DBpedia sur le site : http://en.sparql.pro/wiki/DBpedia
}}
 
== Requêtes ASK ==
=== Résultat ===
Une requête ASK est très proche d'une requête SELECT sauf qu'il n'y a que deux résultats possiblepossibles : true (vrai) ou false (faux).
ou false (faux).
=== Structure d'une requête ===
Elle se divise en 3 parties :
# Définition des préfixes si vous utilisez des IRIs relativesrelatifs
# Définition des jeux de données sur lesquelleslesquels portentporte la requête,. attention,Attention : seulement disponible dans SPARQL 1.1.
# Définition des conditions.
 
<pre>
# Déclaration des préfixes si ils’il y a utilisation d'IRI relativesrelatifs
PREFIX foo: <...> #Pas d’espace entre Le nom du préfixe et Les deux points
PREFIX ...
Ligne 663 ⟶ 672 :
}
</pre>
Une requête renvoie vrai si les conditions de la requête trouvetrouvent au moins une réponse dans les données. S'il n'y a aucune réponse possible, la requête renvoie faux.
 
Prenons les données Dans le graphe RDF/Turtle :
Ligne 681 ⟶ 690 :
Résultat de la requête: '''TRUE'''
 
ParEn contrerevanche, avec la requête SPARQL :
<pre>PREFIX foaf: <http://xmlns.com/foaf/0.1/>
ASK WHERE { ?x foaf:name "Alice" ;
Ligne 707 ⟶ 716 :
}}
 
On peut également décrire plusieurs références sélectionnées en même temps sélectionnéeset qui respectent des conditions.
{{exemple|contenu=
<pre>PREFIX foaf: <http://xmlns.com/foaf/0.1/>