[Narzędzia] Analiza dostępnych implementacji silnika SPARQL
Zespół
Opis
Przegląd (możliwości i ograniczenia), ogólna ocena i przykłady użycia różnych implementacji silników SPARQL.
Wymagania
Spotkania
Projekt
Sprawozdanie
Apache Jena - ARQ
napisany w Javie,
jest częścią Apache Jena (framework do budowy sieci semantycznych),
umożliwia przeszukiwanie tekstu (przy użyciu Apache Lucene) - zarówno samych danych RDF jak i zewnętrznych dokumentów,
w pełni implementuje protokół SPARQL,
umożliwia wykorzystanie zewnętrznych endpointów,
wspiera SPARQL Update,
umożliwia pisanie własnych funkcji filtrujących,
umożliwia wykonywanie zapytań typu FEDERATED,
silnik nie skaluje się dobrze wraz ze wzrostem ilości triples,
posiada dobrą dokumentacje.
Przykład zapytanie typu FEDERATED (użycie SERVICE
):
PREFIX : <http://example/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?a
FROM <mybooks.rdf>
{
?b dc:title ?title .
SERVICE <http://sparql.org/books>
{ ?s dc:title ?title . ?s dc:creator ?a }
}
Przykład implementacji własnej funkcji filtrującej:
public class max extends FunctionBase2
{
public max() { super() ; }
public NodeValue exec(NodeValue nv1, NodeValue nv2)
{
return Functions.max(nv1, nv2) ;
}
}
Wykorzystanie własnych funkcji filtrujących w zapytaniu:
PREFIX f: <java:app.myFunctions.>
...
FILTER f:myTest(?x, ?y)
...
FILTER (?x + f:myIntToXSD(?y))
...
Allegro Graph - twinql
Oprócz SPARQL AllegroGraph wspiera również zapytania RDFS++ i Prologu,
twinql napisany jest w Common Lisp,
-
niepełne wsparcie standardu SPARQL (np. niepełna zgodność z gramatyką SPARQL),
wsparcie dla SPARQL Update,
zwraca rezultaty w formie human-readable listy lub SPARQL XML query results format
,
wyposażony jest w optymalizator i kompilator zapytań,
AllegroGraph i twinql zapewniają stosunkowo dobrą wydajność nawet dla dużych zestawów danych (25-50 milionów triples),
dokumentacja twinql jest dosyć uboga.
Przykład parsowania zapytania:
(parse-sparql
"PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?x ?name
WHERE { ?x foaf:name ?name .
?x foaf:knows ?y . }")
(SPARQL :SELECT
:VARS (|x| |name|)
:WHERE
'(GRAPH-PATTERN (TRIPLE |x| !"foaf:name" |name|)
(TRIPLE |x| !"foaf:knows" |y|)))
Przykład wykonania zapytania:
(sparql :select :distinct t :vars '(name mbox)
:from "http://www.holygoat.co.uk/foaf.rdf"
:where
'(graph-pattern
(triple x !foaf:knows !rich:RichardNewman)
(triple x !foaf:name name)
(triple x !foaf:mbox_sha1sum mbox)))
<?xml version="1.0"?>
<sparql xmlns="http://www.w3.org/2001/sw/DataAccess/rf1/result2">
<head>
<variable name="NAME" />
<variable name="MBOX" />
</head>
<results>
<result>
<binding name="NAME"><literal>Stephen Charles Cook</literal></binding>
<binding name="MBOX"><literal>8a8d159b39d8789fa93c9d000b75f395a723343d</literal></binding>
</result>
<result>
<binding name="NAME"><literal>Timothy Archer Millea</literal></binding>
<binding name="MBOX"><literal>e9e511fb6acd12db93f899c9e28249b782c73f8a</literal></binding>
...
Virtuoso
kompletny framework do tworzenie sieci semantycznych,
niepełne wsparcie standardu SPARQL (m.in. niepełna zgodność z gramatyką SPARQL, brak wsparcie dla Unicode),
implementuje rozszerzenia standardu SPARQL (np. obsługa funkcji agregujących, obsługa wyrażeń wewnątrz triples oraz sekcji WHERE),
wsparcie dla SPARQL Update, SPARQL Create, SPARQL Delete,
możliwość geo-indeksowania,
indeksowanie i wyszukiwanie tekstu,
zapewnia REST-owy interfejs do wykonywania zapytań i innych operacji,
możliwość skonfigurowania do użycia w klastrze,
posiada rozbudowaną dokumentacje,
bardzo dobrze się skaluje.
Przykład wykorzystania operacji INSERT
:
SQL>SPARQL INSERT INTO GRAPH <http://mygraph.com> { <:a>
<:p>
"123 abc" };
callret-0
VARCHAR
_______________________________________________________________________________
Insert into <http://mygraph.com>, 1 triples -- done
1 Rows. -- 30 msec.
SQL>SPARQL INSERT INTO GRAPH <http://mygraph.com> { <:a>
<:p>
"234 abc" };
callret-0
VARCHAR
_______________________________________________________________________________
Insert into <http://mygraph.com>, 1 triples -- done
1 Rows. -- 0 msec.
SELECT
z użyciem funkcji atoi
:
SQL>SPARQL
SELECT *
FROM <http://mygraph.com>
WHERE
{
?s ?p ?o . filter (bif:atoi (?o) > 130)
};
s p o
VARCHAR VARCHAR VARCHAR
___________________________________
:a :p 234 abc
1 Rows. -- 10 msec.
Wykorzystanie funkcji contains
:
SQL>SPARQL
SELECT *
FROM <http://MyTest.com>
WHERE { ?s ?p ?o . ?o bif:contains "world" };
s p o
VARCHAR VARCHAR VARCHAR
_______________________________________________________________________________
sxml1 p_all1 <Hello>world</Hello>
nonxml1 p_all3 Hello world
sxml2 p_all2 <Hello2>world</Hello2>
3 Rows. -- 20 msec.
RDF::Query
napisany w Perlu,
w pełni zgodny ze standardem SPARQL,
współpracuje z RDF::Trine, RDF::Redland i RDF::Core,
obsługuje zapytania RDQL,
posiada dosyć dobrą dokumentacje,
nie jest aktywnie rozwijany (ostatnia aktualizacja w 2012 roku).
Przykład użycia:
# SPARQL SELECT Query
my $query = RDF::Query->new( 'SELECT * WHERE ...' );
my $iterator = $query->execute( $model );
while (my $row = $iterator->next) {
# $row is a HASHref containing variable name -> RDF Term bindings
print $row->{ 'var' }->as_string;
}
# SPARQL CONSTRUCT/DESCRIBE Query
my $query = RDF::Query->new( 'CONSTRUCT { ... } WHERE ...' );
my $iterator = $query->execute( $model );
while (my $st = $iterator->next) {
# $st is a RDF::Trine::Statement object representing an RDF triple
print $st->as_string;
}
# SPARQL ASK Query
my $query = RDF::Query->new( 'ASK WHERE ...' );
my $iterator = $query->execute( $model );
my $bool = $iterator->get_boolean;
if ($bool) {
print "Yes!\n";
}
# RDQL Query
my $query = new RDF::Query ( $rdql, { lang => 'rdql' } );
my @rows = $query->execute( $model ); # in list context, returns all results
ARC2
napisany w PHP,
niepełne wsparcie standardu SPARQL,
implementuje własne rozszerzenia SPARQL (np. funkcje agregujące),
jako backend wykorzystuje MySQL,
pozwala na używanie funkcji MySQL wewnątrz zapytań,
wspiera operacje LOAD
, INSERT
, DELETE
,
posiada dosyć dobrą dokumentacje.
Przykład wykorzystanie funkcji concat
z MySQL:
PREFIX mysql: <http://web-semantics.org/ns/mysql/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?person WHERE {
?person foaf:givenname ?n1 ;
foaf:family_name ?n2 .
FILTER (mysql:concat(?n1, " ", ?n2) = "Alec Tronnick") .
}
Przykład z użyciem agregacji:
SELECT ?who COUNT(?contact) AS ?contacts WHERE {
?who foaf:knows ?contact .
}
GROUP BY ?who
Materiały