SPARQL
SPARQL (pronounced "sparkle", a recursive acronym[2] for SPARQL Protocol and RDF Query Language) is an RDF query language—that is, a semantic query language for databases—able to retrieve and manipulate data stored in Resource Description Framework (RDF) format.[3][4] It was made a standard by the RDF Data Access Working Group (DAWG) of the World Wide Web Consortium, and is recognized as one of the key technologies of the semantic web. On 15 January 2008, SPARQL 1.0 was acknowledged by W3C as an official recommendation,[5][6] and SPARQL 1.1 in March, 2013.[7] SPARQL allows for a query to consist of triple patterns, conjunctions, disjunctions, and optional patterns.[8] Implementations for multiple programming languages exist.[9] There exist tools that allow one to connect and semi-automatically construct a SPARQL query for a SPARQL endpoint, for example ViziQuer.[10] In addition, tools exist to translate SPARQL queries to other query languages, for example to SQL[11] and to XQuery.[12] AdvantagesSPARQL allows users to write queries that follow the RDF specification of the W3C. Thus, the entire dataset is "subject-predicate-object" triples. Subjects and predicates are always URI identifiers, but objects can be URIs or literal values. This single physical schema of 3 "columns" is hyperdenormalized in that what would be 1 relational record with 4 fields is now 4 triples with the subject being repeated over and over, the predicate essentially being the column name, and the object being the field value. Although this seems unwieldy, the SPARQL syntax offers these features: 1. Subjects and Objects can be used to find the other including recursively. Below is a set of triples. It should be clear that
ex:sw001 ex:linksWith ex:sw003 .
ex:sw002 ex:linksWith ex:sw003 .
ex:sw003 ex:linksWith ex:sw004 , ex:sw006 .
ex:sw004 ex:linksWith ex:sw005 .
In SPARQL, the first time a variable is encountered in the expression pipeline, it is populated with result. The second and subsequent times it is seen, it is used as an input. If we assign ("bind") the URI SELECT *
WHERE {
BIND(ex:sw003 AS ?targets)
?src ex:linksWith ?targets . # ?src populated with ex:sw001, ex:sw002
}
But with a simple switch of the binding variable, the behavior is reversed. This will produce all the things upon which SELECT *
WHERE {
BIND(ex:sw003 AS ?src)
?src ex:linksWith ?targets . # NOTICE! No syntax change! ?targets populated with ex:sw004, ex:sw006
}
Even more attractive is that we can easily instruct SPARQL to recursively follow the path: SELECT *
WHERE {
BIND(ex:sw003 AS ?src)
# Note the +; now SPARQL will also find ex:sw005 transitively via ex:sw004; ?targets is ex:sw004, ex:sw005, ex:sw006
?src ex:linksWith+ ?targets .
}
Bound variables can therefore also be lists and will be operated upon without complicated syntax. The effect of this is similar to the following: If ?S is bound to (ex:A, ex:B) and ?O is UNbound then
?S ex:linksWith ?O
behaves like a forward chain:
for each s in ?S:
fetch (s,ex:linksWith), capture o # given 2, get third
append o to ?O
If ?O is bound to (ex:A, ex:B) and ?S is UNbound then
?S ex:linksWith ?O
behaves like a backward chain:
for each o in ?O:
fetch (ex:linksWith,o), capture s # given 2, get third
append s to ?S
Unlike SQL which has subqueries and CTEs, SPARQL is much more like MongoDB or SPARK. Expressions are evaluated exactly in the order they are declared including filtering and joining of data. The programming model becomes what a SQL statement would be like with multiple WHERE clauses. The combination of list-aware subjects and objects plus a pipeline approach can yield extremely expressive queries spanning many different domains of data. Here is a more comprehensive example that illustrates the pipeline using some syntax shortcuts. # SELECT only the terminal values we need. If we did SELECT * (which
# is not nessarily bad), then "intermediate" variables ?vendor and ?owner
# would be part of the output.
SELECT ?slbl ?vlbl ?lei ?lname
WHERE {
# ?sw is unbound. Set predicate to rdf:type and object to ex:Software
# and collect all software instances. At same, pull the software
# label (a terse description) and populate ?slbl and also capture the
# vendor object into ?vendor.
?sw rdf:type ex:Software ;
rdfs:label ?slbl ;
ex:vendor ?vendor .
# The above in "longhand" reveals the binding process:
# ?sw rdf:type ex:Software . # ?sw UNBOUND; is set here
# ?sw rdfs:label ?slbl . # ?sw bound; set unbound ?slbl
# ?sw ex:vendor ?vendor . # ?sw still bound; set ?vendor
# Exclude open souce software. Note ex:oss is an URI because it is
# an UNquoted string:
FILTER(?vendor NOT IN (ex:oss))
# Next, dive into ?vendor object and extract legal entity identifier
# and owner of the data -- where owner is also an object. ?vendor is
# bound; ?vlbl, ?lei, and ?owner are unbound and will be populated:
?vendor rdfs:label ?vlbl ;
ex:LEI ?lei ;
ex:owner ?owner .
# Lastly, from owner object, capture last name:
?owner ex:lastname ?lname .
}
Unlike relational databases, the object column is heterogeneous: the object data type, if not an URI, is usually implied (or specified in the ontology) by the predicate value. Literal nodes carry type information consistent with the underlying XSD namespace including signed and unsigned short and long integers, single and double precision floats, datetime, penny-precise decimal, Boolean, and string. Triple store implementations on traditional relational databases will typically store the value as a string and a fourth column will identify the real type. Polymorphic databases such as MongoDB and SQLite can store the native value directly into the object field. Thus, SPARQL provides a full set of analytic query operations such as The example below demonstrates a simple query that leverages the ontology definition Specifically, the following query returns names and emails of every person in the dataset: PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
?email
WHERE
{
?person a foaf:Person .
?person foaf:name ?name .
?person foaf:mbox ?email .
}
This query joins all of the triples with a matching subject, where the type predicate, " For the sake of readability, the author of this query chose to reference the subject using the variable name " The result of the join is a set of rows – An important consideration in SPARQL is that when lookup conditions are not met in the pipeline for terminal entities like PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
?email
WHERE
{
?person a foaf:Person .
OPTIONAL {
?person foaf:name ?name .
?person foaf:mbox ?email .
}
}
Whether in a federated manner or locally, additional triple definitions in the query could allow joins to different subject types, such as automobiles, to allow simple queries, for example, to return a list of names and emails for people who drive automobiles with a high fuel efficiency. Query formsIn the case of queries that read data from the database, the SPARQL language specifies four different query variations for different purposes.
Each of these query forms takes a SPARQL 1.1 specifies a language for updating the database with several new query forms.[13] ExampleAnother SPARQL query example that models the question "What are all the country capitals in Africa?": PREFIX ex: <http://example.com/exampleOntology#>
SELECT ?capital
?country
WHERE
{
?x ex:cityname ?capital ;
ex:isCapitalOf ?y .
?y ex:countryname ?country ;
ex:isInContinent ex:Africa .
}
Variables are indicated by a The SPARQL query processor will search for sets of triples that match these four triple patterns, binding the variables in the query to the corresponding parts of each triple. Important to note here is the "property orientation" (class matches can be conducted solely through class-attributes or properties – see Duck typing). To make queries concise, SPARQL allows the definition of prefixes and base URIs in a fashion similar to Turtle. In this query, the prefix "
SELECT ?lbl ?version ?released ?eol ?duration
WHERE {
?software a ex:Software ;
rdfs:label ?lbl ;
ex:EOL ?eol ; # is xsd:dateTime
ex:version ?version ; # string
ex:released ?released ; # is xsd:dateTime
# After this stage, ?duration is bound as xsd:duration type
# and is available in the pipeline, in the SELECT, and in
# GROUP or ORDER operators, etc.:
BIND(?eol - ?released AS ?duration)
# Duration is of format PnYnMnDTnHnMnS. Note that in SPARQL, all
# literals are strings so we must use ^^ casting to tell the engine
# this is to be treated as a duration:
FILTER(?duration >= "P1000D"^^xsd:duration && YEAR(?released) >= 2020)
}
ORDER BY DESC(?duration)
LIMIT 5
ExtensionsGeoSPARQL defines filter functions for geographic information system (GIS) queries using well-understood OGC standards (GML, WKT, etc.). SPARUL is another extension to SPARQL. It enables the RDF store to be updated with this declarative query language, by adding XSPARQL is an integrated query language combining XQuery with SPARQL to query both XML and RDF data sources at once.[14] ImplementationsOpen source, reference SPARQL implementations
See List of SPARQL implementations for more comprehensive coverage, including triplestore, APIs, and other storages that have implemented the SPARQL standard. See alsoReferences
External linksWikimedia Commons has media related to SPARQL.
|