Accueil > Prise en charge des requêtes fédérées
Prise en charge des requêtes fédérées (mot-clé SERVICE)
Le problème
SPARQL et le web sémantique en général ont la capacité de fonctionner dans des contextes distribués et de résoudre des requêtes contre plus d’un point d’accès SPARQL. Cependant, cela est compliqué à comprendre pour un utilisateur, et encore plus compliqué pour un utilisateur de spécifier quelle partie de sa requête doit être dirigée vers quel service SPARQL.
La solution
À partir de la version 8, Sparnatural fournit une prise en charge de base pour les requêtes fédérées en utilisant le mot-clé SERVICE
. L’idée est que les requêtes fédérées seront activées pour certaines propriétés dans votre configuration, que vous devez configurer à l’avance. Une fois configurée, l’utilisation des requêtes fédérées sera transparente pour l’utilisateur, qui n’aura pas à définir quoi que ce soit lors de la rédaction de sa requête.
Pour configurer les requêtes fédérées, vous devez :
- Déclarer le point d’accès vers lequel vous souhaitez envoyer les requêtes fédérées, en créant une instance de
sd:Service
- Indiquer l’URL du point d’accès SPARQL de ce service en utilisant la propriété
sd:endpoint
- Lier des propriétés spécifiques dans votre configuration à ce point d’accès en utilisant l’annotation
core:sparqlService
.
Dans les requêtes impliquant ces propriétés spécifiques, toute la “branche” de la requête utilisant cette propriété sera automatiquement entourée d’un mot-clé SERVICE
.
Nous illustrerons cette configuration avec des requêtes fédérées sur Wikidata.
Configuration en SHACL
- Ajoutez une annotation
http://data.sparna.fr/ontologies/sparnatural-config-core#sparqlService
sur une forme de propriété qui doit être exécutée en tant que SERVICE - Cette annotation pointera vers une entité qui est elle-même le sujet d’un prédicat
http://www.w3.org/ns/sparql-service-description#endpoint
contenant l’URL réelle du point d’accès SPARQL - Optionnellement, vous pouvez ajouter
http://data.sparna.fr/ontologies/sparnatural-config-core#executedAfter
sur la forme de propriété pour forcer le reste de la requête à être placé dans une sous-requête qui sera évaluée avant que la clause SERVICE ne soit envoyée
PREFIX core: <http://data.sparna.fr/ontologies/sparnatural-config-core#>
PREFIX sd: <http://www.w3.org/ns/sparql-service-description#>
ex:myNodeShape a sh:NodeShape ;
sh:property ex:myProperty .
ex:myProperty sh:path ex:myProperty ;
# use custom annotation to link the property to the SPARQL service
# the SPARQL service indicates its endpoint with the sd:endpoint property
core:sparqlService [sd:endpoint <https://vocab.getty.edu/sparql> ] ;
# rdfs:label ...
# the remote part of the query will be executed after the rest
core:executedAfter true ;
.
Configuration en OWL
La manière courte et simple en Turtle
Si vous éditez la configuration en Turtle, une configuration pourrait ressembler à ceci :
PREFIX core: <http://data.sparna.fr/ontologies/sparnatural-config-core#>
PREFIX sd: <http://www.w3.org/ns/sparql-service-description#>
ex:myProperty owl:subPropertyOf core:NonSelectableProperty ;
# use custom annotation to link the property to the SPARQL service
# the SPARQL service indicates its endpoint with the sd:endpoint property
core:sparqlService [sd:endpoint <https://vocab.getty.edu/sparql> ] ;
# rdfs:label ...
.
Configuration dans Protégé
Déclarer une instance de sd:Service
sd:Service
est une classe déclarée dans le vocabulaire de Description de Service SPARQL. Elle est incluse pour vous dans l’ontologie de configuration Sparnatural, donc vous n’avez pas besoin d’ajouter une importation.
Dans Protégé, créez une instance de cette classe et donnez-lui l’URI que vous souhaitez, par exemple https://www.wikidata.org
:
Déclarer l’URL de l’endpoint
Alors que l’URI du Service peut être ce que vous voulez, vous devez formellement déclarer l’URL technique à laquelle le service écoute en utilisant la propriété sd:endpoint
sur cette instance.
Dans Protégé, vous êtes obligé de d’abord déclarer une instance de owl:Thing avec l’URL pour pouvoir la sélectionner ultérieurement (si vous éditez votre configuration manuellement, vous n’avez pas besoin de le faire).
Créez une instance de owl:Thing et donnez-lui l’URL précise du point d’extrémité SPARQL, dans notre cas https://query.wikidata.org/
:
Ensuite, revenez à votre individu de Service, éditez-le et ajoutez une assertion de propriété d’objet avec le prédicat sd:endpoint
et la valeur https://query.wikidata.org/
. Dans Protégé, vous êtes obligé de passer d’abord à “View > Render by prefixed name” pour pouvoir sélectionner votre URL de point d’extrémité :
Lier une propriété au service
Maintenant que notre service est prêt, nous pouvons indiquer qu’une propriété dans notre configuration doit être routée vers ce Service. Nous le faisons avec la propriété core:sparqlService
. Par exemple, nous pourrions imaginer qu’une propriété pour récupérer les coordonnées géographiques utilise la fédération pour récupérer la géométrie depuis Wikidata :
Notez comment :
- nous sélectionnons le service www.wikidata.org, pas l’URL https://query.wikidata.org
- Notre propriété est associée à
<http://www.wikidata.org/prop/direct/P625>
qui est l’identifiant de propriété dans Wikidata contenant les coordonnées géo.
et… TADAM !
Maintenant, lorsqu’une requête est émise impliquant cette propriété, elle est automatiquement enveloppée dans une clause SERVICE en utilisant l’URL de l’endpoint :
Configuration supplémentaire (expérimentale) : executedAfter
Certaines - sinon la plupart - des cas d’utilisation de requêtes fédérées impliquent de d’abord interroger le triplestore local, récupérer quelques URIs, et ensuite récupérer certaines propriétés de ces URIs dans un triplestore fédéré distant. Et non l’inverse. Pour que ce type de requête réussisse, nous devons indiquer à Sparnatural d’exécuter d’abord la partie locale de la requête, et ensuite la partie distante de la requête. Cela implique d’envelopper la première partie de la requête dans une clause SELECT imbriquée.
Cela peut être réalisé en définissant un drapeau supplémentaire (expérimental) config:executedAfter
sur la propriété :
PREFIX core: <http://data.sparna.fr/ontologies/sparnatural-config-core#>
PREFIX sd: <http://www.w3.org/ns/sparql-service-description#>
ex:myProperty owl:subPropertyOf core:NonSelectableProperty ;
# use custom annotation to link the property to the SPARQL service
# the SPARQL service indicates its endpoint with the sd:endpoint property
core:sparqlService [sd:endpoint <https://vocab.getty.edu/sparql> ] ;
# the remote part of the query will be executed after the rest
core:executedAfter true ;
# rdfs:label ...
De cette manière, la requête SPARQL générée ressemblera à ceci : (notez l’utilisation du SELECT interne) :
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?ProvidedCHO_1 ?ProvidedCHO_1_label WHERE {
{
SELECT * WHERE {
?ProvidedCHO_1 rdf:type <http://www.europeana.eu/schemas/edm/ProvidedCHO>.
OPTIONAL {
?ProvidedCHO_1 (^<http://www.openarchives.org/ore/terms/proxyFor>/<http://purl.org/dc/elements/1.1/title>) ?ProvidedCHO_1_label.
FILTER((LANG(?ProvidedCHO_1_label)) = "en")
}
?ProvidedCHO_1 (^<http://www.openarchives.org/ore/terms/proxyFor>/<http://purl.org/dc/elements/1.1/type>) ?Type_2.
}
}
SERVICE <https://vocab.getty.edu/sparql> {
?Type_2 (<http://www.w3.org/2004/02/skos/core#scopeNote>/rdf:value) ?ScopeNote_4.
FILTER((LANG(?ScopeNote_4)) = "en")
}
}
LIMIT 1000