SPARQL Query Andy Seaborne
Apache Jena he.org/jena ● Open source - Apache License ● Apache Incubator (accepted November 2010) ● Old web site: ● RDF: parsers and writers ● SPARQL: Query, Update, Server
SPARQL 1.1 ● SPARQL Query ● Sub-queries ● Aggregation ● Negation ● Property Paths ● SPARQL Update ● Language ● Protocol ● Other ● Entailment ● Service Description ● Function Library
Recap: Basic Graph Pattern ● Basic graph patterns ● Building blocks of SPARQL queries ● A number of triples, all of which mush match. PREFIX rdf: PREFIX foaf: SELECT ?name WHERE { ?x rdf:type foaf:Person ; foaf:name ?name. } PREFIX rdf: PREFIX foaf: SELECT ?name WHERE { ?x rdf:type foaf:Person. ?x foaf:name ?name. }
SPARQL Subquery and aggregation PREFIX rdf: PREFIX foaf: SELECT (count(*) AS ?count) { ?x rdf:type foaf:Person. } | count | ========= | 12 |
SPARQL Subquery and aggregation PREFIX rdf: PREFIX foaf: SELECT ?group (count(*) AS ?count) { ?x rdf:type foaf:Person. ?group foaf:member ?x. } GROUP BY ?group | group | count | =============================== | | 4 | | | 3 |
Example: All people who know 3 others PREFIX rdf: PREFIX foaf: SELECT ?name { { SELECT ?x (count(*) AS ?count) { ?x foaf:knows ?y. } GROUP BY ?x HAVING (?count = 3) } ?x foaf:name ?name. } | name | ============ | "Clare" | | "Brenda" | | "Alice" |
Aggregate Functions ● COUNT ● MIN ● MAX ● SUM ● AVG ● GROUP_CONCAT ● SAMPLE
Negation ● 2 forms – stylistic and conceptual differences ● Absence of a pattern ● Removing rows from a result set ● Nearly the same, but not quite
Negation ● Example: People without declared name PREFIX rdf: PREFIX foaf: SELECT ?x { ?x rdf:type foaf:Person. FILTER NOT EXISTS { ?x foaf:name ?name } } PREFIX rdf: PREFIX foaf: SELECT ?x { ?x rdf:type foaf:Person. MINUS { ?x foaf:name ?name } }
Negation : NOT EXISTS ● Filters results by a pattern ● Tests applied to each row ● Variables substituted for values for that row ● EXISTS version also in SPARQL { ?x rdf:type foaf:Person. FILTER NOT EXISTS { ?x foaf:name ?name } } ({?x = :X}, {?x = :Y} ) :X rdf:type foaf:Person. :X foaf:name “Xavier”. :Y rdf:type foaf:Person. 1: ({?x = :X}) test { :X foaf:name ?name } => triple pattern exists 2: ({?x = :Y}) test { :Y foaf:name ?name } => triple pattern does not exist ( {?x = :Y} )
Negation : Differences SELECT * { ?s ?p ?o FILTER NOT EXISTS { ?x ?y ?z } } SELECT * { ?s ?p ?o MINUS { ?x ?y ?z } } SELECT * { ?s ?p ?o FILTER NOT EXISTS { } } SELECT * { ?s ?p ?o MINUS { } } SELECT * { ?s :p ?o FILTER ( NOT EXISTS { ?s :q ?v. FILTER (?o < ?v ) } ) } SELECT * { ?s :p ?o MINUS { ?s :q ?v. FILTER (?o < ?v ) } ) }
Property Paths ● Regular expressions over properties ● Simple paths : adds easy of expressibility ● Concat ● Alternate ● {N} ● {N,M} ● Adds arbitrary length paths ● :p*, :p+ ● Paths can combine other paths
Property Paths : Simple Path Example PREFIX rdf: PREFIX foaf: SELECT ?xName ?yName { ?x rdf:type foaf:Person. ?x foaf:name ?xName ?x foaf:knows{2}/foaf:name ?yName. } { ?x rdf:type foaf:Person. ?x foaf:name ?xName ?x foaf:knows ?_2. ?_2 foaf:knows ?_1. ?_1 foaf:name ?yName. } { ?x rdf:type foaf:Person. ?x foaf:name ?xName ?x foaf:knows{2} ?_1. ?_1 foaf:name ?yName. }
Property Paths and Inference rdfs:subClassOf PREFIX rdf: PREFIX rdfs: PREFIX : SELECT ?s { ?s rdf:type ?T. ?T rdfs:subClassOf* :SomeClass. }
Property Paths and Inference rdfs:subPropertyOf PREFIX rdf: PREFIX rdfs: PREFIX : SELECT * { ?s ?p ?o. ?p rdfs:subPropertyOf* :property. }
Property Path : Accessing RDF rdf:. :x :p (“a” “b” rdf:. :x :p _:b1. _:b1 rdf:first “a”. _:b1 rdf:rest _:b2. _:b2 rdf:first “b”. _:b2 rdf:rest _:b3. _:b3 rdf:first “c”. _:b3 rdf:rest rdf:nil. :x_:b1 rdf:rest rdf:first “a” :p _:b2 rdf:rest rdf:first “b” _:b3 rdf:rest rdf:first “c” rdf:nil
Property Path : Accessing RDF lists ● Partial solution ● Order in list not visible PREFIX rdf: PREFIX rdfs: PREFIX : SELECT ?member { :x :p ?list. ?list rdf:rest*/rdf:first ?member. }
SPARQL 1.1 Update ● Fine grain graph manipulations ● Act on a “graph store” ● Add and remove graphs ● Act on the contents of graphs ● Quad centric ● LOAD, DROP, CREATE ● INSERT, DELETE ● Data and patterns ● One request is multiple operations
Data Operations PREFIX rdf: PREFIX foaf: DELETE DATA { foaf:name “DEF”. } ; INSERT DATA { foaf:name “ABC”. } ;
Data Operations PREFIX rdf: PREFIX foaf: DELETE DATA { GRAPH { foaf:name “DEF”. } } ; INSERT DATA { GRAPH { foaf:name “ABC”. } } ;
Empty Graphs Graph stores not required to know about empty graphs. ● Quads stores with no graph management can't distinguish no graph (no quads) from empty graph (no quads) ● Stores that are collections of graphs often do have an “empty graph”
Pattern Operations : DELETE-INSERT PREFIX foaf: PREFIX vc: DELETE { ?p vc:fn ?x } INSERT { ?p foaf:name ?x } WHERE { GRAPH { ?p vc:fn ?x. ?p foaf:knows } } Pattern → Delete triples → Insert triples
Other INSERT and DELETE forms # INSERT with template-pattern INSERT { ?p foaf:name ?x } WHERE { GRAPH { ?p vc:fn ?x. ?p foaf:knows } } # DELETE with template-pattern DELETE { ?p foaf:name ?x } WHERE { GRAPH { ?p foaf:name ?x } } # DELETE WHERE DELETE WHERE { foaf:name ?x } ; DELETE WHERE { GRAPH { foaf:name ?x } } ;
Graph Management CREATE ; CREATE SILENT ; DROP ; DROP SILENT ; DROP ALL ; DROP NAMED ;
LOAD ; LOAD INTO GRAPH ; CLEAR DEFAULT ; CLEAR ALL ; CLEAR NAMED ; CLEAR GRAPH ; CLEAR SILENT GRAPH ; Whole Graph Operations
# ADD : triples added to a graph. # Source unchanged. ADD :graph1 TO DEFAULT ; ADD :graph1 TO ; # MOVE # Old contents lost. # Rename a graph MOVE :graph TO :graph2 ; # COPY # Copy over triples # Old contents lost. # Graph 2 is the same triples as :graph1. COPY :graph TO :graph2 ;
Q & A
PREFIX : PREFIX rdf: SELECT (?s1 AS ?subset) (?s2 AS ?superset) WHERE { ?s2 rdf:type :Set. ?s1 rdf:type :Set. FILTER(?s1 != ?s2) MINUS { ?s1 rdf:type :Set. ?s2 rdf:type :Set. FILTER(?s1 != ?s2) ?s1 :member ?x. FILTER NOT EXISTS { ?s2 :member ?x. } :. :a rdf:type :Set. :a :member 1. :a :member 2. :a :member 3. :b rdf:type :Set. :b :member 1. :b :member 9. :c rdf:type :Set. :c :member 1. :c :member 2. :d rdf:type :Set. :d :member 1. :d :member 9. :e rdf:type :Set. :e :member 1. :e :member 2. :empty rdf:type :Set. PREFIX : PREFIX rdf: SELECT (?s1 AS ?subset) (?s2 AS ?superset) WHERE { ?s2 rdf:type :Set. ?s1 rdf:type :Set. FILTER(?s1 != ?s2) MINUS { ?s1 rdf:type :Set. ?s2 rdf:type :Set. FILTER(?s1 != ?s2) ?s1 :member ?x. FILTER NOT EXISTS { ?s2 :member ?x. } :. :a rdf:type :Set. :a :member 1. :a :member 2. :a :member 3. :b rdf:type :Set. :b :member 1. :b :member 9. :c rdf:type :Set. :c :member 1. :c :member 2. :d rdf:type :Set. :d :member 1. :d :member 9. :e rdf:type :Set. :e :member 1. :e :member 2. :empty rdf:type :Set. Negation Use Case: Subset