Como escrever consulta SPARQL que forma eficiente corresponde literais de seqüência de caracteres, ignorando o caso
Pergunta
Eu estou usando Jena ARQ escrever uma consulta SPARQL contra uma grande ontologia a ser lido a partir de Jena TDB, a fim de encontrar os tipos associados com os conceitos baseados no rdfs rótulo:
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 .
}
Isso funciona muito bem e é bastante rápida (<1 segundo).Infelizmente, para alguns termos, o que eu preciso para realizar esse tipo de consulta em um case-insensitive forma.Por exemplo, porque o rótulo "Tylenol"
é na ontologia, mas não "tylenol"
, a consulta a seguir vem a vazio:
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 .
}
Sou capaz de escrever um case-insensitive versão deste consulta usando a sintaxe do FILTRO, como por exemplo:
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") )
}
Mas, agora, a consulta leva mais de um minuto para concluir!Existe alguma maneira para escrever o case-insensitive consulta de uma forma mais eficiente?
Solução
O motivo da consulta com o FILTRO de consulta é executada mais lentamente porque ?o termo é independente requer a digitalização do PSO ou POS de índice para encontrar todas as instruções com o rdfs:label predicado e filtrá-los contra a regex.Quando ele foi vinculado a um recurso concreto (no primeiro exemplo), ele poderia usar uma OPS ou POS índice para digitalizar através de instruções apenas com o rdfs:label predicado e o objeto especificado de recursos, o que teria um valor muito mais baixo de cardinalidade.
A solução comum para este tipo de pesquisa de texto problema é usar um externo índice de texto.Neste caso, Jena oferece um índice de texto chamado LARQ, que usa o Lucene para realizar a pesquisa e junta-se os resultados com o resto da consulta.
Outras dicas
De todos os possíveis operadores seqüência de caracteres que você pode usar em SPARQL, regex
é, provavelmente, o mais caro.A sua consulta pode executar mais rápido se você evitar regex
e você usa UCASE
ou LCASE
em ambos os lados do teste em vez disso.Algo como:
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")
}
Isso pode ser mais rápido, mas em geral não esperam um ótimo desempenho para pesquisa de texto com qualquer triplo loja.Triplo lojas são muito bons no gráfico de correspondência e não tão bom em seqüência de caracteres correspondente.