Come scrivere la query dello sparql che corrisponde in modo efficiente i letterali della stringa mentre ignorano il caso
Domanda
Sto usando Jena Arq per scrivere una query sparql contro una grande ontologia Leggi da Jena TDB per trovare i tipi associati ai concetti basati sull'etichetta 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 .
}
.
funziona abbastanza bene ed è in realtà abbastanza veloce (<1 secondo).Sfortunatamente, per alcuni termini, ho bisogno di eseguire questa query in modo inconsensionale.Ad esempio, poiché l'etichetta "Tylenol"
è nell'ontologia, ma non in "tylenol"
, la seguente query viene vuota vuota:
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 .
}
.
Posso scrivere una versione insensibile di questa query usando la sintassi del filtro come:
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") )
}
.
Ma ora la query richiede un minuto da completare!C'è un modo per scrivere la query insensibile caso in modo più efficiente?
Soluzione
Il motivo La query con la query del filtro viene eseguita più lento è perché? Termine è il suo non è necessario eseguire la scansione dell'indice PSO o POS per trovare tutte le istruzioni con i RDF: etichetta predicato e filtrarle contro la regex.Quando è stato associato a una risorsa concreta (nel tuo primo esempio), potrebbe utilizzare un indice OPS o POS per eseguire la scansione solo di dichiarazioni con i RDF: il predicato dell'etichetta e la risorsa oggetto specificata, che avrebbe una cardinalità molto più bassa.
.La soluzione comune a questo tipo di problema di ricerca del testo è utilizzare un indice di testo esterno.In questo caso, Jena fornisce un indice di testo gratuito chiamato larq , che useLucene per eseguire la ricerca e si unisce ai risultati con il resto della query.
Altri suggerimenti
Da tutti i possibili operatori di stringa che è possibile utilizzare in Sparql, regex
è probabilmente il più costoso.La tua query potrebbe essere eseguita più veloce se si evita regex
e si utilizza UCASE
o LCASE
su entrambi i lati del test.Qualcosa come:
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")
}
.
Questo potrebbe essere più veloce ma in generale non aspettatevi grandi prestazioni per la ricerca di testo con qualsiasi negozio triplo.I negozi tripli sono molto buoni nella corrispondenza del grafico e non sono così buoni nella corrispondenza delle corde.