Consultando bases de datos semánticas

alibobo_w3cSPARQL-logo

 

Tutorial¿Qué es RDF y para que es bueno?

Una base de datos semántica, también llamada repositorio de triples dado que guarda triples (los cuales si se recuerda, no son más que otra palabra para las sentencias RDF), es generalmente cualquier repositorio de sentencias RDF que soporte algún tipo de operación de consulta. Esto es importante por supuesto, ya que una vez que se tiene un documento, lo ideal es preguntar que tiene por dentro.

El proceso de consultar se concentra en los datos abstractos, ignorando como fueron almacenados originalmente los triples (XML, Notation3, etc.). Como resultado, los repositorios de triples omiten muchas veces en que orden se almacenaron las sentencias originalmente, que nombre de espacio, prefijo y nombre local fueron usados para un tipo de recurso específico, o que nombre local fue utilizado para identificar a los nodos en blanco dentro de los documentos. Estos artefactos incidentales usados para serializar RDF no son parte del contenido informativo de los documentos (Después de todo, se supone que deben ser olvidados).

Lo que un repositorio de triples si puede decirte es que sentencias están almacenadas dentro (De manera desordenada). Usualmente el repositorio puede responder la pregunta de si una sentencia en particular está contenida en él, y algunos serán capaces de proveer una serie de sentencias que coincidan con un patrón dado.

A estos repositorios es válido dividirlos en dos tipos. Por un lado tenemos repositorios puros, aquellos que almacenan sentencias y responden preguntas con respecto a su existencia. Por otro lado tenemos repositorios que pueden responder preguntas mucho más complicadas que se basan en semántica RDFS y OWL, o en reglas lógicas provistas especialmente. A continuación se hablará de estos últimos.

Para una lista de aplicaciones que almacenan triples, por favor visitar LargeTripleStores.

De la misma manera que los RDBMS y el estándar XML lo tienen, existe un lenguaje de consultas estándar y es llamado SPARQL. La similaridad lexicográfica con SQL no es un accidente. SPARQL es un lenguaje de consultas para RDF modelado para asemejarse a SQL, aunque difieren bastante. En adición, el estándar SPARQL es solo para realizar consultas, no existen funciones para agregar o modificar el contenido de una sentencia. Eso si, algunos repositorios soportan este tipo de operaciones, pero no bajo el estándar SPARQL.

Tal y como se hizo con la introducción de Notation3 y RDF/XML en secciones anteriores, se tratará de proveer los principios básicos bajo los cuales funciona el lenguaje SPARQL. Empecemos con datos de ejemplo de un hipotético repositorio de datos en RDF.

RDF sobre “mi apartamento”.

@prefix ex: <http://example.org/> .
@prefix taubz: <http://razor.occams.info/index.html#> .

taubz:me              ex:own         taubz:my_apartment .
taubz:me              ex:own         taubz:my_computer .
taubz:my_apartment    ex:contains    taubz:my_computer .
taubz:my_apartment    ex:contains    taubz:friends_junk .
taubz:my_apartment    ex:location    <http://example.org/Philadelphia> .
taubz:me              ex:own         taubz:my_desk .
taubz:my_desk         ex:contains    taubz:my_pens_and_pencils .

El lenguaje contiene cuatro tipos de consultas: SELECT, ASK, DESCRIBE y CONSTRUCT.

La consulta de tipo SELECT es la más similar a SQL ya que se provee una consulta y se retorna una respuesta tabular, sin embargo la similaridad termina allí. En la consulta SELECT de SPARQL se espera encontrar recursos. Por ejemplo, una consulta puede preguntar que recursos “posee” “mi apartamento”. Explicado sería, ¿Qué recursos X pueden ser encontrados en el repositorio en sentencias de tipo X   ex:own   taubz:my_apartment?. La respuesta de acuerdo a los datos planteados anteriormente sería taubz:me. Otro ejemplo de consulta sería: ¿Qué recursos están en mi apartamento? o lo que es lo mismo, que recursos son los objetos X de las sentencias tipo taubz:my_apartment   ex:contains   X. Esto difiere de SQL ya que cada fila de resultados es una fila de una tabla, mientras que acá cada fila es un recurso.

SPARQL, al igual que SQL, tiene una clausula WHERE, sim embargo en SPARQL es un patrón de grafos. Un patrón de grafos es como un grafo, en formato Notation3, excepto que además de URIs, bnodes y literales, también se permite el uso de variables. Las variables son marcadores de posición, precisamente como la X usada anteriormente. Las variables representan los recursos que se están buscando. La segunda pregunta que se formuló anteriormente se escribe en SPARQL de la siguiente forma:

 Ejemplo SPARQL #1

PREFIX ex: <http://example.org/>
PREFIX taubz: <http://razor.occams.info/index.html#>
SELECT ?what
WHERE {
    taubz:my_apartment ex:contains ?what .
}

El resultado sería:

 Resultado SPARQL #1

     ?what
-----------------
taubz:my_computer
taubz:friends_junk

Debemos tener en consideración lo siguiente. Primero, el nombre de la variable ?what is incidental, tal y como se tratan el resto de los nombres en RDF, excepto que debe iniciar con ‘?’. Segundo, mientras que algunas cosas se parecen a N3, tal y como la sintaxis de grafos, las otras partes no lo hacen (Las declaraciones PREFIX por ejemplo). Por último, la salida de una consulta SPARQL es una tabla. Como se accede a la tabla depende del motor SPARQL que se use. Sin embargo, existe un formato de salida estándar en XML. Para este caso no importa el formato usado.

El patrón de grafos puede contener más de una sentencia. Esto tiene el efecto de 1) filtrar los recursos que pueden ser retornados, o 2) consultar basado en caminos más largos a través del repositorio de datos. Por ejemplo, para preguntar que está en “mi apartamento” que a la vez “poseo”, se filtran los resultados para contener únicamente los recursos que se poseen mediante una segunda sentencia en el grafo.

 Ejemplo SPARQL #2

PREFIX ex: <http://example.org/>
PREFIX taubz: <http://razor.occams.info/index.html#>
SELECT ?what
WHERE {
    taubz:my_apartment ex:contains ?what .
    **taubz:me ex:own ?what .**
}

El resultado sería:

 Resultado SPARQL #2

     ?what
-----------------
taubz:my_computer

Cada recurso retornado debe ser capaz de ser sustituido en todas las ocurrencias de la variable ?what, de tal manera que cada sentencia en el patrón de grafos exista en el repositorio. El recurso taubz:friends_junk es descartado dado que cuando sustituimos ese recurso en el grafo nos queda:

taubz:my_apartment ex:contains taubz:friends_junk .
**taubz:me ex:own taubz:friends_junk .**

Y una de estas sentencias, específicamente la segunda, no existe en el repositorio.

Una consulta para encontrar recursos contenidos en cualquier objeto que “poseo” (taubz:my_computer el cual está contenido en el apartamento, al igual que taubz:friends_junk, y taubz:my_pens_and_pencils los cuales están en el escritorio) usaría un patrón de grafos que tiene un camino más largo a través de los recursos del repositorio.  Esta consulta podría ser expresada como una conjunción de dos sentencias, como antes, pero esta vez usando dos variables. Esto es: Por cualquier par de recursos xy que podamos encontrar, tal que A)   taubz:me ex:own y   y B)   y ex:contains x, reportar el recurso x. Aquí está la consulta SPARQL y la respuesta esperada:

 Ejemplo SPARQL #3

PREFIX ex: <http://example.org/>
PREFIX taubz: <http://razor.occams.info/index.html#>
SELECT ?what
WHERE {
    **taubz:me ex:own ?container .
    ?container ex:contains ?what .**
}

 Resultado SPARQL #3

         ?what
-------------------------
taubz:my_computer
taubz:friends_junk
taubz:my_pens_and_pencils

Para sacarle más partida aún, en vez de preguntar solo por la lista de objetos podemos preguntar por los pares de valores de ?container?what que van juntos. El único cambio es agregar la variable ?container a la sentencia SELECT:

 Ejemplo SPARQL #4

PREFIX ex: <http://example.org/>
PREFIX taubz: <http://razor.occams.info/index.html#>
SELECT **?container** ?what
WHERE {
    taubz:me ex:own ?container .
    ?container ex:contains ?what .
}

 Resultado SPARQL #4

   ?container               ?what
------------------  -------------------------
taubz:my_apartment  taubz:my_computer
taubz:my_apartment  taubz:friends_junk
taubz:my_desk       taubz:my_pens_and_pencils

Cada fila es verificada al sustituir, por cada una de las variables del grafo, el valor correspondiente listado en esa fila, una fila al tiempo. Al igual que antes, si después de la sustitución de todos los valores en las sentencias ocurre una coincidencia, la fila se incluye en el resultado.

Antes de concluir, acá tenemos un poco de terminología. Dentro de cualquier fila en particular dentro del resultado, se dice que una variable es “atada” por el valor de esa variable en esa fila. En la primera fila de la tabla en el ejemplo 4, la variable ?container es atada por taubz:my_apartment.

Hasta una futura revisión de este artículo, no se tratará más profundamente el tema de SPARQL.

Para más información acerca de la especificación de SPARQL, visite el siguiente sitio web.

Anuncios

Un comentario Agrega el tuyo

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s