Wikidata, SPARQL et chiens de traîneaux
Bon, puisque le dernier billet semble avoir plu, je vais continuer de poster ici mes bidouillages avec SPARQL. L’hiver arrive à grands pas et la saison des courses de chiens de traîneaux aussi par la même occasion, donc c’est parti pour des requêtes un peu plus touchy avec des photos de chiots, parce qu’il n’y a pas de raison de ne pas en profiter.
UNION
Pour commencer, j’aimerais bien avoir toutes les courses de chiens de traîneaux pour lesquelles des participants sont enregistrés. Problème : il y a des courses pour lesquelles la nature de l’élément (P31) est course de chiens de traîneaux (Q1968664), d’autres pour lesquelles la nature est un élément concernant une course qui est elle-même une sous-classe (P279) de course de chiens de traîneaux, et enfin d’autres pour lesquelles la nature est un élément concernant une course qui n’est pas marquée comme sous-classe de course de chiens de traîneaux… Mais pour lequel « course de chiens de traîneaux » est indiqué comme sport (P641). Bref, c’est le bordel. On va donc faire les deux requêtes en même temps et en joindre les résultats avec la commande UNION, comme ci-dessous.
PREFIX wd: <http://www.wikidata.org/entity/> PREFIX wdt: <http://www.wikidata.org/prop/direct/> PREFIX wikibase: <http://wikiba.se/ontology#> PREFIX p: <http://www.wikidata.org/prop/> PREFIX v: <http://www.wikidata.org/prop/statement/> PREFIX q: <http://www.wikidata.org/prop/qualifier/> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> select distinct ?course ?courseLabel where { { ?course wdt:P31/wdt:P279* wd:Q1968664 . } UNION { ?course wdt:P31/wdt:P641* wd:Q1968664 . } ?course wdt:P710 ?musher . SERVICE wikibase:label { bd:serviceParam wikibase:language "fr,en" . } } ORDER BY ?courseLabel
Comme dit ci-dessus, quand la même chose peut être décrite sous deux formes, on peut faire une union pour joindre les résultats des deux requêtes :
{ ?course wdt:P31/wdt:P279* wd:Q1968664 . } UNION { ?course wdt:P31/wdt:P641* wd:Q1968664 . }
La ligne suivante :
?course wdt:P710 ?musher .
sert à restreindre aux courses ayant un ou des valeurs pour la propriété « participant » (P710)
Pour finir, je trie par ordre alphabétique des noms en français des courses :
ORDER BY ?courseLabel
Qualificatifs
J’aimerais maintenant chercher, dans les participants à des courses de chiens de traîneau, ceux qui n’ont pas de rang à l’arrivée d’indiqué, ni d’événement-clef expliquant pourquoi ils ne sont pas arrivés (par exemple, abandon ou disqualification). Ces informations sont mises en qualificatifs de la déclaration :
Ici, dans les participants de l’Iditarod 2015, on voit que Brent Sass a été disqualifié (il y a même un article de Wikinews expliquant pourquoi), et que Jason Mackey est arrivé 42e.
On ne peut pas chercher ça avec wdt:, qui renvoie une valeur. Il nous faut utiliser une autre des ontologies proposées par défaut, p:, qui renvoie une déclaration en entier, avec tous ses qualificatifs. La requête est donc la suivante :
PREFIX wd: <http://www.wikidata.org/entity/> PREFIX wdt: <http://www.wikidata.org/prop/direct/> PREFIX wikibase: <http://wikiba.se/ontology#> PREFIX p: <http://www.wikidata.org/prop/> PREFIX v: <http://www.wikidata.org/prop/statement/> PREFIX q: <http://www.wikidata.org/prop/qualifier/> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> select distinct ?course ?courseLabel ?musherLabel where { { ?course wdt:P31/wdt:P279* wd:Q1968664 . } UNION { ?course wdt:P31/wdt:P641* wd:Q1968664 . } ?course p:P710 ?musherS . ?musherS v:P710 ?musher . FILTER NOT EXISTS { ?musherS q:P1352 ?rang . } FILTER NOT EXISTS { ?musherS q:P793 ?event . } SERVICE wikibase:label { bd:serviceParam wikibase:language "fr,en" . } } ORDER BY ?courseLabel
La première ligne du WHERE
n’a pas changé par rapport à la requête précédente.
Dans la deuxième, en revanche, on voit que wdt: a été remplacé par p:.
?course p:P710 ?musherS .
J’ai aussi renommé ?musher
par ?musherS
pour me rappeler que c’est une déclaration (statement) et non une valeur directement. Pour pouvoir afficher le nom des mushers, je vais devoir chercher ladite valeur en utilisant le préfixe v:
et la même propriété, avec la déclaration comme sujet :
?musherS v:P710 ?musher .
Enfin, deux filtres sur les qualificatifs (on utilise donc q: et non p: cette fois) me permettent de remonter les lignes qui n’ont pas (FILTER NOT EXISTS
) de rang (P1352) ni d’événement-clef (P793).
FILTER NOT EXISTS { ?musherS q:P1352 ?rang . } FILTER NOT EXISTS { ?musherS q:P793 ?event . }
Je crois que je vais continuer à m’amuser un peu avec les courses de chiens la prochaine fois, et voir dans quoi on peut réinjecter les résultats des requêtes, pour générer des graphiques ou des cartes…