3.2 Arquitectura da Semantic Web
3.2.5 SPARQL Protocol and RDF Query Language
Após a aceitação da RDF por parte do W3C, como método genérico para a descrição conceptual ou modelação de informação que é implementada em recursos Web, logo se colocou o problema natural de se criar uma linguagem para pesquisas em dados RDF. Várias linguagens foram propostas desde então, como por exemplo: a linguagem RQL (Karvounarakis, Alexaki et al., 2002), SeRQL (Karvounarakis, Alexaki et al., 2002), RDQL (Seaborne, 2004), entre outras. Em (Haase, Broekstra et al., 2004) os autores fazem uma breve descrição e comparação destas e outras linguagens de pesquisas para RDF. Em 2004 o
Data Access Working Group publicou a primeira versão do esboço de uma linguagem para
pesquisas em dados RDF, chamada SPARQL (Prud'hommeaux and Seaborne, 2005), que é actualmente é uma recomendação do W3C (Prud'hommeaux and Seaborne, 2008).
A SPARQL é uma linguagem para executar queries em diferentes tipos de fontes de dados, quer eles estejam armazenados no formato nativo RDF, quer possam ser vistos como dados RDF através de um qualquer middleware. Fornece ainda facilidades para extrair informação em forma de URIs, nós do tipo blank nodes ou bnodes (representa um recurso sem URI), literais e subgrafos RDF, e permite construir novos grafos RDF baseados na informação de
queries prévias.
Algumas das características que a SPARQL fornece são:
construir uma query que contém um grafo composto através de uma ou mais triplas RDF para ser correspondido na fonte de dados;
− capacidade de os resultados serem devolvidos como um subgrafo do grafo de dados original;
− explorar dados através de pesquisas em relações desconhecidas;
− suporte a queries locais e remotas. As fontes de dados podem estar armazenadas localmente ou remotamente;
− executar junções complexas de diferentes base de dados num única query;
− transformar dados RDF de um vocabulário para outro;
− suporte para definir um número máximo de resultados;
− a linguagem SPARQL é baseada na correspondência de padrões de grafos. O padrão mais simples do grafo é a tripla, que é como uma tripla RDF mas com a possibilidade de colocar uma variável no lugar de um dos termos sujeito, ou objecto. 1: PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 2: PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 3: SELECT ?c 4: FROM <http://www.daml.org/2003/01/periodictable/PeriodicTable.owl> 5: WHERE { 6: ?c rdf:type rdfs:Class . 7: }
Código 3.8 – Exemplo de uma query SPARQL básica.
O Código 3.8 mostra um exemplo de uma query SPARQL simples. Esta query irá retornar todas as triplas que tenham propriedade rdf:type e objecto rdf:Class, isto é, irá retornar todas as classes que o grafo contém. Tal como a RDF/XML a SPARQL também usa um mecanismo de namespace para definir os prefixos para os namespaces. Isso é feito no início da query com a palavra PREFIX para declarar os namespaces, o que permite construir
queries mais curtas e simples de ler.
A seguir à declaração dos namespaces vem a palavra SELECT, tal como no SQL a instrução é definida para que dados irão sejam retornados na query. A palavra FROM identifica os dados onde a query irá actuar, neste caso a query será realizada numa tabela periódica em RDF referida pelo URI. Uma query pode incluir múltiplas fontes correspondendo nesse caso a múltiplas palavras-chave FROM. A instrução WHERE indica o grafo a ser procurado e que é
constituído por uma ou mais triplas e que irão ser correspondidas no grafo.
A parte de correspondência da query pode incluir triplas opcionais. Este tipo de triplas são úteis para realizar queries que retornem dados se estes estiverem disponíveis, e não rejeitar a solução se parte da query normalizada não corresponder. A correspondência opcional fornece essa facilidade: se as parte opcionais não correspondem ela não cria ligações mas também não elimina a solução. Estas partes podem ainda ser juntas, isto é, unir vários grafos normalizados para correspondência através da palavra UNION: se ocorrer algumas das correspondências então será retornado um resultado. A sequência de resultados pode ser ainda alterada utilizando umas das palavras-chave com significado similar ao SQL:
− ORDER BY – ordenar pelo valor de uma variável;
− DISTINCT – apenas devolver resultados únicos;
− LIMIT – número máximo de resultados;
− OFFSET – offset a partir do qual os valores serão apresentados.
Existem ainda quatro tipo de queries, são elas:
− SELECT – já apresentada anteriormente, retorna o valor das variáveis descritas na
query de pesquisa;
− CONSTRUCT – retorna um grafo RDF construído substituindo as variáveis descritas na query;
− DESCRIBE – retorna um grafo RDF descrevendo os recursos que foram encontrados;
− ASK – retorna um valor booleano indicando se o grafo padrão definido na query foi encontrado ou não.
A query do Código 3.9 ilustra o exemplo de uma query do tipo ASK para determinar se um dispositivo iPhone possui ou não GPS e terá um resultado do tipo booleano.
1: PREFIX devi: <http://icas.ipb.pt/secom/device> 2: ASK {
3: ?dev devi:hasDeviceComponent ddevi:GPS . 4: ?dev devi:deviceModel ?deviceModel . 5: FILTER regex(?deviceModel, “iPhone”) 6: }
O Código 3.10 mostra outro exemplo de uma query SPARQL, que retorna todos os nós (pessoas) que contenham o nome Pedro na propriedade hasName.
1: PREFIX acto: <http://icas.ipb.pt/secom/actor>
2: SELECT ?hasFirstName ?hasName ?hasSurName ?hasBirthday WHERE { 3: ?person acto:hasName ?hasName .
4: ?person acto:hasFirstName ?hasFirstName . 5: ?person acto:hasSurName ?hasSurName . 6: ?person acto:hasBirthday ?hasBirthday . 7: FILTER regex(?hasName, “Pedro”)
8: }
Código 3.10 – Exemplo de uma query SELECT à ontologia Actor do modelo SeCoM.
Os resultados das queries SPARQL podem ser em dois formatos: conjunto de resultados e grafos RDF. Os conjuntos de resultados são ilustrados de uma forma tabelar, como aparece na Tabela 3.5.
Tabela 3.5 – Resultado da query do Código 3.10 no formato conjunto de resultados.
hasFirstName hasName hasSurName hasBirthday “João” “João Pedro” “Marques” “12/02/1979” “Pedro” “Pedro João” “Santos” “09/09/1971” “José” “José Pedro” “Fernandes” “16/01/1980”
O resultado acima no formato conjunto de resultados, pode depois ser serializado em XML (Beckett and Broekstra, 2008), como mostra o Código 3.11.
1: <?xml version="1.0"?> 2: <sparql xmlns="http://www.w3.org/2005/sparql-results#"> 3: <head> 4: <variable name="hasFistName"/> 5: <variable name="hasName"/> 6: <variable name="hasSurName"/> 7: <variable name="hasBirthday"/> 8: </head> 9: <results> 10: <result> 11: <binding name="hasFistName"> 12: <literal>João</literal> 13: </binding> 14: <binding name="hasName"> 15: <literal>João Pedro</literal> 16: </binding> 17: <binding name="hasSurName"> 18: <literal>Marques</literal> 19: </binding> 20: <binding name="hasBirthday"> 21: <literal>12/02/1979</literal> 22: </binding>2 23: </result> 24: <result> 25: <binding name="hasFistName"> 26: <literal>Pedro</literal>
27: </binding> 28: <binding name="hasName"> 29: <literal>Pedro João</literal> 30: </binding> 31: <binding name="hasSurName"> 32: <literal>Santos</literal> 33: </binding> 34: <binding name="hasBirthday"> 35: <literal>09/09/1971</literal> 36: </binding> 37: ... 38: </result> 39: </results> 40: </sparql>
Código 3.11 - Resultado da query do Código 3.10 serializado em XML
As queries que pode retornar o formato grafo RDF são as queries DESCRIBRE e CONSTRUCT. O Código 3.12 mostra o exemplo de uma query CONSTRUCT mais simples.
1: PREFIX acto: <http://icas.ipb.pt/secom/actor>
2: PREFIX rela: <http://icas.ipb.pt/secom/relationship> 3:
4: CONSTRUCT { ?p acto:hasFirstName ?hasFirstName } 5: WHERE { ?x rela:isFriendof ? ?hasFirstName }
Código 3.12 – Exemplo de uma query do tipo CONTRUCT.
O resultado da query CONSTRUCT poderia ser o grafo RDF representado no Código 3.13. Este grafo é construído baseado num modelo que é usado para gerar triplas RDF segundo o resultado da correspondência do grafo padrão da query, como mostra o Código 3.13.
1: @prefix <acto: http://icas.ipb.pt/secom/actor> 2:
3: _:x acto:hasFirstName "João" . 4: _:y acto:hasFirstName "José" .
Código 3.13 – Grafo RDF como resultado da query do Código 3.12.
O Código 3.14. é o resultado serializado em RDF/XML retornado pela query definida no Código 3.13. 1: <rdf:RDF 2: xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 3: xmlns:acto=”http://icas.ipb.pt/secom/actor"> 4: <rdf:Description> 5: <acto:hasFirstName >José</foaf:hasFirstName > 6: </rdf:Description> 7: <rdf:Description> 8: <acto:hasFirstName>José</acto:hasFirstName > 9: </rdf:Description> 10: </rdf:RDF>
Juntamente com a linguagem SPARQL foi desenvolvido o SPARQL Protocol, que transporta as queries dos clientes até aos processadores de queries (Figura 3.8). O SPARQL Protocol é descrito de dois modos: o primeiro utilizando uma interface abstracta de qualquer implementação ou protocolo usando para isso a WSDL 2.0; e o segundo é a utilização do HTTP e SOAP para ligar a essa interface. Os resultados são devolvidos em XML sendo o formato do documento definido pela SPARQL Query Results XML. Por fim, o motor de inferência extrai os dados das fontes RDF ou de outras fontes de informação, através de ferramentas de conversão, como por exemplo, as linguagens de descrição de recurso GRDDL (Connolly, 2007) e RDFa (Adida, Birbeck et al., 2008).
Figura 3.8 – Modelo genérico de uma aplicação cliente a realizar queries a um motor de inferência.
Como uma linguagem de queries, a SPARQL apenas pesquisa informação em grafos, isto é não existe nenhum mecanismo de inferência na própria linguagem. Alguns motores de inferência podem no entanto aparentar que certas triplas existem através da sua criação em tempo real, utilizando um motor de inferência baseado em RDFS, como por exemplo o ARQ, um processador SPARQL para a framework Jena (Hewlett-Packard, 2009).
Embora existam várias implementações que usam a sintaxe SPARQL como linguagem de
query em grafos RDF e existem também muitas expectativas na possibilidade de usar a
SPARQL para pesquisar OWL. Uma das propostas que mais se destaca é a SPARQL DL, que segundo os autores em (Sirin and Parsia, 2007) é significativamente mais expressiva do que as
Existem diversas ferramentas e APIs que suportam motores de queries SPARQL. A maior parte deles está actualizado com a sua última especificação e alguns deles serão abordados na secção 3.3.1.