
Ce document présente les requêtes qui, pour un concept donné C, permettent de retrouver et d'ordonner l'ensemble des resources MICA qui y sont liées par une annotation (soit parcequ'elles sont directement annotées par le concept C, soit parcequ'elles sont annotées par un ou des sous concepts de C).
Tout au long de ce document, pour simplifier l'écriture des URIs désignant les resources, les prefixes suivants sont utilisés :
Par exemple
Pour expliquer et tester les différentes requêtes présentées dans ce document nous travaillons sur le jeu de données suivant :
Sept concepts sont définis de manière hiérarchique:
Cinq ressources de type MICASheet sont définies et annotées par les concepts précédents.
La figure qui suit présente le graphe RDF correspondant à ce jeu de données (seules les relations hiérarchiques entre concepts et les annotations des resources MICA sont représentées).

Ce jeu de données est défini (en notation Turtle) dans le fichier RankingTestData.ttl
@prefix micavocab: <https://w3id.org/mica/ontology/MicaOntology/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix micaresource: <https://w3id.org/mica/resource/> .
@prefix micamodel: <https://w3id.org/mica/ontology/MicaModel#> .
#Concepts
micavocab:C1_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:prefLabel "C1".
micavocab:C1_1_1
a skos:Concept ;
skos:broader micavocab:C1_1 ;
skos:inScheme micavocab:DomainScheme ;
skos:prefLabel "C1_1".
micavocab:C1_1_2
a skos:Concept ;
skos:broader micavocab:C1_1 ;
skos:inScheme micavocab:DomainScheme ;
skos:prefLabel "C1_2".
micavocab:C1_1_1_1
a skos:Concept ;
skos:broader micavocab:C1_1_1 ;
skos:inScheme micavocab:DomainScheme ;
skos:prefLabel "C1_1_1".
micavocab:C1_1_1_2
a skos:Concept ;
skos:broader micavocab:C1_1_1 ;
skos:inScheme micavocab:DomainScheme ;
skos:prefLabel "C1_1_2".
micavocab:C1_1_1_3
a skos:Concept ;
skos:broader micavocab:C1_1_1 ;
skos:inScheme micavocab:DomainScheme ;
skos:prefLabel "C1_1_3".
micavocab:C1_1_1_2_1
a skos:Concept ;
skos:broader micavocab:C1_1_1_2 ;
skos:inScheme micavocab:DomainScheme ;
skos:prefLabel "C1_1_2_1".
#Sheets
micaresource:S1
a micamodel:MICASheet ;
dcterms:title "S1" ;
micamodel:hasDomainConcept micavocab:C1_1_1 .
micaresource:S2
a micamodel:MICASheet ;
dcterms:title "S2" ;
micamodel:hasDomainConcept micavocab:C1_1_1_1,micavocab:C1_1_1_2_1 .
micaresource:S3
a micamodel:MICASheet ;
dcterms:title "S3" ;
micamodel:hasDomainConcept micavocab:C1_1_1_3 .
micaresource:S4
a micamodel:MICASheet ;
dcterms:title "S4" ;
micamodel:hasDomainConcept micavocab:C1_1_1_2,micavocab:C1_1_1_3 .
micaresource:S5
a micamodel:MICASheet ;
dcterms:title "S5" ;
micamodel:hasDomainConcept micavocab:C1_1_2 .Étant donné le fait qu’on a configuré les inferences sur les concepts, tous les concepts qui annotés une ressource, contiennnent le predicate hasMICAConcept. Ce qui implique le fait qu’on peut traiter tous les concepts de la même façon sans se soucier de leur ontologie respective.
Pour chercher un type de ressource donnée, on precise dans la requête le type.
Par exemple:
Pour les exemples suivants, on cherche les Sheets qui sont annotés par le concept C1_1_1_1 ou ses sous concepts.
Dans ce cas, on sélectionne les sheets par leur URI ?sheetURI et les concepts qui les annotés par leur URI ?conceptURI
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX micavocab: <https://w3id.org/mica/ontology/MicaOntology/>
PREFIX model: <https://w3id.org/mica/ontology/MicaModel#>
PREFIX micaresource: <https://w3id.org/mica/resource/>
SELECT ?sheetURI ?conceptURI
WHERE {
?sheetURI a model:Sheet;
model:hasMicaConcept ?conceptURI.
?conceptURI skos:broaderTransitive micavocab:C1_1 ;
}
order by ?sheetURI ?conceptURILe résultat de la requête
| sheetURI | conceptURI |
| micaresource:S1 | micavocab:C1_1 |
| micaresource:S2 | micavocab:C1_1_1 |
| micaresource:S2 | micavocab:C1_1_2_1 |
| micaresource:S3 | micavocab:C1_1_3 |
| micaresource:S4 | micavocab:C1_1_2 |
| micaresource:S4 | micavocab:C1_1_3 |
Les différents cas qu’on peut avoir:
si un sheet est annoté par
Dans ce cas, on aura une seule fois sheetURI pour un sheet donné.
Dans ce cas, on aura plusieurs fois SheetURI pour un sheet donné. C’est pouquoi, il faut grouper les concepts via une deuxième sélection.
Pour avoir une fois, ?sheetURI par chaque sheet et l'ensemble de concepts sous forme d’un String, on utilise la fonction SPARQL group_concat et on sépare des concepts par une virgule.
La requête précédente devient :
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX micavocab: <https://w3id.org/mica/ontology/MicaOntology/>
PREFIX model: <https://w3id.org/mica/ontology/MicaModel#>
PREFIX micaresource: <https://w3id.org/mica/resource/>
SELECT ?sheetURI
(group_concat( ?conceptURI; separator =";" )AS ?conceptURIs)
WHERE {
SELECT ?sheetURI ?conceptURI
WHERE {
?sheetURI a model:Sheet;
model:hasMicaConcept ?conceptURI.
?conceptURI skos:broaderTransitive micavocab:C1_1 ;
}
}
GROUP BY ?sheetURI ?conceptURIsLe résultat de la requête
| sheetURI | conceptURIs |
| micaresource:S3 | "micavocab:C1_1_3" |
| micaresource:S4 | "micavocab:C1_1_3;micavocab:C1_1_2" |
| micaresource:S1 | "micavocab:C1_1" |
| micaresource:S2 | "micavocab:C1_1_1;micavocab:C1_1_2_1" |
Jusqu’ici, on vient de faire la recherche de sheets mais ils ne sont pas encore ordonné. pour ce faire, nous avons besoin de compter le nombre de parents de chaque concepts et ordonne le résultat par ce nombre.
La requête de l'étape 2 devient :
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX micavocab: <https://w3id.org/mica/ontology/MicaOntology/>
PREFIX model: <https://w3id.org/mica/ontology/MicaModel#>
PREFIX micaresource: <https://w3id.org/mica/resource/>
SELECT ?sheetURI ?conceptURI (COUNT(distinct ?parentURI) as ?nbParentURI)
WHERE {
?sheetURI a model:Sheet;
model:hasMicaConcept ?conceptURI.
?conceptURI skos:broaderTransitive micavocab:C1_1 ;
skos:broaderTransitive ?parentURI.
}
GROUP BY ?sheetURI ?conceptURI ?nbParentURI
ORDER BY ?nbParentURI ?sheetURI ?conceptURIDans ce cas, on a encore le même problème que pour l'étape 1 car un sheet peut être annoté par plusieurs concepts, On compte le nombre de parents pour chaque concept. il y aura plusieurs fois ?sheetURI pour un sheet donné.
Le résultat de la requête
| sheetURI | conceptURI | nbParentURI |
| micaresource:S1 | micavocab:C1_1 | "2"^^xsd:integer |
| micaresource:S2 | micavocab:C1_1_1 | "3"^^xsd:integer |
| micaresource:S3 | micavocab:C1_1_3 | "3"^^xsd:integer |
| micaresource:S3 | micavocab:C1_1_2 | "3"^^xsd:integer |
| micaresource:S4 | micavocab:C1_1_3 | "3"^^xsd:integer |
| micaresource:S2 | micavocab:C1_1_2_1 | "4"^^xsd:integer |
Pour éviter la redondance de ?sheetURI,on calcule le nombre de parents pour le concept de référence qui est dans notre cas C1_1_1_1.
La requête de l'étape 3 devient :
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX micavocab: <https://w3id.org/mica/ontology/MicaOntology/>
PREFIX model: <https://w3id.org/mica/ontology/MicaModel#>
PREFIX micaresource: <https://w3id.org/mica/resource/>
SELECT ?sheetURI
(group_concat( ?conceptURI; separator =";" ) AS ?conceptURIs)
(min(?nbParentURI-?nbParentRefURI) as ?rank)
WHERE {
SELECT ?sheetURI ?conceptURI
(COUNT(distinct ?parentURI) as ?nbParentURI)
(COUNT( distinct ?parentRefURI) as ?nbParentRefURI)
WHERE {
?sheetURI a model:Sheet;
model:hasMicaConcept ?conceptURI.
?conceptURI skos:broaderTransitive micavocab:C1_1 ;
skos:broaderTransitive ?parentURI.
micavocab:C1_1 skos:broaderTransitive ?parentRefURI.
}
GROUP BY ?sheetURI ?conceptURI
}
GROUP BY ?sheetURI
ORDER BY ?rank ?sheetURI ?conceptURIsTout d’abord, on cherche le nombre de parents de la réference ensuite,on cherche le nombre des parents de chaque concept.
Si il n' y a pas des exaequos, on n’a l’ordre des sheets avec le paramètre ?rank
Le résultat de la requête
| sheetURI | conceptURIs | rank |
| micaresource:S1 | "micavocab:C1_1" | "0"^^xsd:integer |
| micaresource:S2 | "micavocab:C1_1_1;micavocab:C1_1_2_1" | "1"^^xsd:integer |
| micaresource:S3 | "micavocab:C1_1_3" | "1"^^xsd:integer |
| micaresource:S4 | "micavocab:C1_1_3;micavocab:C1_1_2_1" | "1"^^xsd:integer |
Si il y a des exaequos, c’est un peu complique.
L’algorithme suivant est proposé dans le cas où il y a des exaequos. Dans ce cas, on calcule la distance la plus éloigne. c’est à dire le sheet annoté par un concept le plus éloigne sera dernière.
La requête de l'étape 4 devient :
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX micavocab: <https://w3id.org/mica/ontology/MicaOntology/>
PREFIX model: <https://w3id.org/mica/ontology/MicaModel#>
PREFIX micaresource: <https://w3id.org/mica/resource/>
SELECT ?sheetURI
(group_concat( ?conceptURI; separator =";" )AS ?conceptURIs)
(min(?nbParentURI-?nbParentRefURI) as ?rank)
(max(?nbParentURI-?nbParentRefURI) as ?nbmax)
WHERE {
SELECT ?sheetURI ?conceptURI
(COUNT(distinct ?parentURI) as ?nbParentURI)
(COUNT( distinct ?parentRefURI) as ?nbParentRefURI)
WHERE {
?sheetURI a model:Sheet;
model:hasMicaConcept ?conceptURI.
?conceptURI skos:broaderTransitive micavocab:C1_1 ;
skos:broaderTransitive ?parentURI.
micavocab:C1_1 skos:broaderTransitive ?parentRefURI.
}
GROUP BY ?sheetURI ?conceptURI
}
GROUP BY ?sheetURI
ORDER BY ?rank ?nbmax ?sheetURI Le résultat de la requête
| sheetURI | conceptURIs | rank | ?nbmax |
| micaresource:S1 | "micavocab:C1_1" | "0"^^xsd:integer | "0"^^xsd:integer |
| micaresource:S4 | "micavocab:C1_1_3;micavocab:C1_1_2" | "1"^^xsd:integer | "1"^^xsd:integer |
| micaresource:S2 | "micavocab:C1_1_1;micavocab:C1_1_2_1" | "1"^^xsd:integer | "2"^^xsd:integer |
| micaresource:S3 | "micavocab:C1_1_3" | "1"^^xsd:integer | "1"^^xsd:integer |
Si les distances nbmax sont égaux aussi. On propose l'étape suivante.
Pour cet étape, le nombre de concepts qui annotent les sheets exaequos, permet les partager. Le sheet ayant un nombre inférieur de concepts annotés sera considéré comme le moins important. Alors que le sheet ayant un nombre supérieur sera considéré comme le plus important.
La requête del'étape 5 devient :
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX micavocab: <https://w3id.org/mica/ontology/MicaOntology/>
PREFIX model: <https://w3id.org/mica/ontology/MicaModel#>
PREFIX micaresource: <https://w3id.org/mica/resource/>
SELECT ?sheetURI
(group_concat( ?conceptURI; separator =";" )AS ?conceptURIs)
(min(?nbParentURI-?nbParentRefURI) as ?rank)
(max(?nbParentURI-?nbParentRefURI) as ?nbmax)
(COUNT(distinct ?conceptURI) as ?nbConceptURIs)
WHERE {
SELECT ?sheetURI ?conceptURI
(COUNT(distinct ?parentURI) as ?nbParentURI)
(COUNT( distinct ?parentRefURI) as ?nbParentRefURI)
WHERE {
?sheetURI a model:Sheet;
model:hasMicaConcept ?conceptURI.
?conceptURI skos:broaderTransitive micavocab:C1_1 ;
skos:broaderTransitive ?parentURI.
micavocab:C1_1 skos:broaderTransitive ?parentRefURI.
}
GROUP BY ?sheetURI ?conceptURI
}
GROUP BY ?sheetURI
ORDER BY ?rank ?nbmax DESC(?nbConceptURIs) ?sheetURILe résultat de la requête
| sheetURI | conceptURIs | rank | nbmax | nbConceptURIs |
| micaresource:S1 | "micavocab:C1_1" | "0"^^xsd:integer | "0"^^xsd:integer | "1"^^xsd:integer |
| micaresource:S4 | "micavocab:C1_1_3;micavocab:C1_1_2" | "1"^^xsd:integer | "1"^^xsd:integer | "2"^^xsd:integer |
| micaresource:S2 | "micavocab:C1_1_1;micavocab:C1_1_2_1" | "1"^^xsd:integer | "2"^^xsd:integer | "2"^^xsd:integer |
| micaresource:S3 | "micavocab:C1_1_3" | "1"^^xsd:integer | "1"^^xsd:integer | "1"^^xsd:integer |
Pour expliquer et tester l'algorithme nous allons travailler sur le jeu de données suivant :
les concepts sont définis de manière hiérarchique:
Les ressources de type MICASheet sont définies et annotées par les concepts précédents.
La figure qui suit présente le graphe RDF correspondant à ce jeu de données (seules les relations hiérarchiques entre concepts et les annotations des resources MICA sont représentées).
Ce jeu de données est défini (en notation Turtle) dans le fichier RankingTestData2.ttl
@prefix micavocab: <https://w3id.org/mica/ontology/MicaOntology/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix micaresource: <https://w3id.org/mica/resource/> .
@prefix micamodel: <https://w3id.org/mica/ontology/MicaModel#> .
#Concepts
micavocab:C0
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:prefLabel "C0".
micavocab:C1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C0 ;
skos:prefLabel "C1".
micavocab:C1_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C1 ;
skos:prefLabel "C1_1".
micavocab:C1_2
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C1 ;
skos:prefLabel "C1_2".
micavocab:C1_1_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C1_1 ;
skos:prefLabel "C1_1_1".
micavocab:C1_2_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C1_2 ;
skos:prefLabel "C1_2_1".
micavocab:C2
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C0 ;
skos:prefLabel "C2".
micavocab:C2_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C2 ;
skos:prefLabel "C2_1".
micavocab:C2_2
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C2 ;
skos:prefLabel "C2_2".
micavocab:C2_1_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C2_1 ;
skos:prefLabel "C2_1_1".
micavocab:C2_2_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C2_2 ;
skos:prefLabel "C2_2_1".
micavocab:C3
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C0 ;
skos:prefLabel "C3".
micavocab:C3_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C3 ;
skos:prefLabel "C3_1".
micavocab:C3_2
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C3 ;
skos:prefLabel "C3_2".
micavocab:C3_1_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C3_1 ;
skos:prefLabel "C3_1_1".
micavocab:C3_2_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C3_2 ;
skos:prefLabel "C3_2_1".
micavocab:C4
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C0 ;
skos:prefLabel "C4".
micavocab:C4_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C4 ;
skos:prefLabel "C4_1".
micavocab:C4_2
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C4 ;
skos:prefLabel "C4_2".
micavocab:C4_1_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C4_1 ;
skos:prefLabel "C4_1_1".
micavocab:C4_2_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C4_2 ;
skos:prefLabel "C4_2_1".
micavocab:C5
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C0 ;
skos:prefLabel "C5".
micavocab:C5_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C5 ;
skos:prefLabel "C5_1".
micavocab:C5_2
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C5 ;
skos:prefLabel "C5_2".
micavocab:C5_1_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C5_1 ;
skos:prefLabel "C5_1_1".
micavocab:C5_2_1
a skos:Concept ;
skos:inScheme micavocab:DomainScheme ;
skos:broader micavocab:C5_2 ;
skos:prefLabel "C5_2_1".
#Sheets
micaresource:S1
a micamodel:MICASheet ;
dcterms:title "S1" ;
micamodel:hasDomainConcept micavocab:C1,micavocab:C2, micavocab:C3,micavocab:C4 .
micaresource:S2
a micamodel:MICASheet ;
dcterms:title "S2" ;
micamodel:hasDomainConcept micavocab:C1,micavocab:C2, micavocab:C3 .
micaresource:S3
a micamodel:MICASheet ;
dcterms:title "S3" ;
micamodel:hasDomainConcept micavocab:C1 .
micaresource:S4
a micamodel:MICASheet ;
dcterms:title "S4" ;
micamodel:hasDomainConcept micavocab:C1_1,micavocab:C2 .
micaresource:S5
a micamodel:MICASheet ;
dcterms:title "S5" ;
micamodel:hasDomainConcept micavocab:C1_2,micavocab:C2_2, micavocab:C3_1,micavocab:C4 .
micaresource:S6
a micamodel:MICASheet ;
dcterms:title "S6" ;
micamodel:hasDomainConcept micavocab:C4_2 .
micaresource:S7
a micamodel:MICASheet ;
dcterms:title "S7" ;
micamodel:hasDomainConcept micavocab:C1_2,micavocab:C2_1_1.
micaresource:S8
a micamodel:MICASheet ;
dcterms:title "S8" ;
micamodel:hasDomainConcept micavocab:C1_1_1.
micaresource:S9
a micamodel:MICASheet ;
dcterms:title "S9" ;
micamodel:hasDomainConcept micavocab:C2_2_1,micavocab:C3_1_1,micavocab:C4_1.
micaresource:S10
a micamodel:MICASheet ;
dcterms:title "S10" ;
micamodel:hasDomainConcept micavocab:C3_2_1,micavocab:C4_2_1.
micaresource:S11
a micamodel:MICASheet ;
dcterms:title "S11" ;
micamodel:hasDomainConcept micavocab:C5.pour cet exemple, nous allons chercher à classer les ressources annotées par micavocab:C1,micavocab:C2, micavocab:C3,micavocab:C4
pour ce faire, on cherche d'abord les ressources annotées par chaque concept ou sous concepts. en utilisant, la requête suivante:
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX micavocab: <https://w3id.org/mica/ontology/MicaOntology/>
PREFIX model: <https://w3id.org/mica/ontology/MicaModel#>
PREFIX micaresource: <https://w3id.org/mica/resource/>
SELECT ?sheetURI
(group_concat( ?conceptURI; separator =";" )AS ?conceptURIs)
(min(?nbParentURI-?nbParentRefURI) as ?rank)
(max(?nbParentURI-?nbParentRefURI) as ?nbmax)
(COUNT(distinct ?conceptURI) as ?nbConceptURIs)
WHERE {
SELECT ?sheetURI ?conceptURI
(COUNT(distinct ?parentURI) as ?nbParentURI)
(COUNT( distinct ?parentRefURI) as ?nbParentRefURI)
WHERE {
?sheetURI a model:Sheet;
model:hasMicaConcept ?conceptURI.
?conceptURI skos:broaderTransitive micavocab:C1 ;
skos:broaderTransitive ?parentURI.
micavocab:C1 skos:broaderTransitive ?parentRefURI.
}
GROUP BY ?sheetURI ?conceptURI
}
GROUP BY ?sheetURI
ORDER BY ?rank ?nbmax DESC(?nbConceptURIs) ?sheetURIOn remplace micavocab:C1 par l'URI du concept cherché: les résultats de cette requête permet de créer un candidate ressource avec un score
le diagramme UML suivant illustre le fonctionnement de candidate Ressource

Voici l'algorithme est le suivant:
pour chaque ressource annotée, on cherche le score ensuite on ajoute le score et le candidat dans la liste des candidats et puis on calcule le nombre d'appartion d'un candidate dans les differents requêtes
on classe par l'ordre decroissante de ce nombre, plus une ressource est apparu dans plusieurs recherches, plus la ressource est bien classée. si deux ressources sont égaux on va les classer en fonction de leurs scores , ce qui implique le calcul pour chaque candidat des paramètres suivants:
une fois ces trois paramètres calcules
on ordonne les classement par rankTotal l'ordre croissante
si il y a des exaequos, on ordonne par le nbMaxTotal l'ordre croissante
si il y a des exaequos, on ordonne par le nbConceptsURITotal