Comment écrire une requête SPARQL qui correspond efficacement aux littéraux de chaîne tout en ignorant la casse

StackOverflow https://stackoverflow.com//questions/10660030

  •  11-12-2019
  •  | 
  •  

Question

J'utilise Jena ARQ pour écrire une requête SPARQL sur une grande ontologie en cours de lecture depuis Jena TDB afin de trouver les types associés aux concepts basés sur l'étiquette rdfs :

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> "aspirin" .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
}

Cela fonctionne plutôt bien et est en fait assez rapide (<1 seconde).Malheureusement, pour certains termes, je dois effectuer cette requête sans tenir compte de la casse.Par exemple, parce que l'étiquette "Tylenol" est dans l'ontologie, mais pas "tylenol", la requête suivante apparaît vide :

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> "tylenol" .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
}

Je peux écrire une version insensible à la casse de cette requête en utilisant la syntaxe FILTER comme ceci :

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> ?term .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
 FILTER ( regex (str(?term), "tylenol", "i") )
}

Mais maintenant, la requête prend plus d’une minute !Existe-t-il un moyen d'écrire la requête insensible à la casse de manière plus efficace ?

Était-ce utile?

La solution

La raison pour laquelle la requête avec la requête FILTER s'exécute plus lentement est que ?term n'est pas lié, il nécessite d'analyser l'index PSO ou POS pour trouver toutes les instructions avec le prédicat rdfs:label et les filtrer par rapport à l'expression régulière.Lorsqu'il était lié à une ressource concrète (dans votre premier exemple), il pouvait utiliser un index OPS ou POS pour analyser uniquement les instructions avec le prédicat rdfs:label et la ressource objet spécifiée, qui auraient une cardinalité beaucoup plus faible.

La solution courante à ce type de problème de recherche de texte consiste à utiliser un index de texte externe.Dans ce cas, Jena fournit un index de texte libre appelé LARQ, qui utilise Lucene pour effectuer la recherche et joint les résultats au reste de la requête.

Autres conseils

Parmi tous les opérateurs de chaîne possibles que vous pouvez utiliser dans SPARQL, regex est probablement le plus cher.Votre requête pourrait s'exécuter plus rapidement si vous évitez regex et tu utilises UCASE ou LCASE des deux côtés du test à la place.Quelque chose comme:

SELECT DISTINCT ?type WHERE {
 ?x <http://www.w3.org/2000/01/rdf-schema#label> ?term .
 ?x <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type .
 FILTER (lcase(str(?term)) = "tylenol")
}

Cela pourrait être plus rapide, mais en général, ne vous attendez pas à de grandes performances pour la recherche de texte avec un triple magasin.Les magasins triples sont très bons pour la correspondance de graphiques et moins bons pour la correspondance de chaînes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top