SPARQL Basics
Query patterns for Waratah, worked against the --load-demo dataset so
every example below can be run as-is (see
Getting Started). The dataset:
| Subject | Predicate | Object |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
All examples share one prefix declaration:
PREFIX ex: <http://ex/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
The basic pattern
A WHERE block lists the statement shapes to match; variables (?name)
are the slots to fill. Patterns that share a variable join, exactly like
a join between tables:
SELECT ?person ?weather WHERE {
?person ex:livesIn ?city .
?city ex:hasWeather ?weather .
}
Result: alice/Sunny, bob/Cold. The shorthand a stands for
rdf:type, so ?person a ex:Person matches people only.
FILTER: keep the rows you want
FILTER applies a condition to each solution:
SELECT ?city WHERE {
?city ex:hasWeather ?weather .
FILTER(?weather = "Sunny")
}
Result: brisbane. Comparisons (=, !=, <, >, ⇐, >=) on
typed literals use their datatypes — dates and date-times compare
chronologically, numbers numerically — which is what makes
Temporal Data range queries work.
OPTIONAL: match what is there
OPTIONAL keeps solutions even when the inner pattern finds nothing;
the variables it would bind are simply left unbound:
SELECT ?city ?raining WHERE {
?city a ex:City .
OPTIONAL { ?city ex:hasRaining ?raining }
}
Both cities come back; ?raining is empty in both rows because nothing
in the dataset has that predicate. This is the standard shape for
"attribute may be absent" data.
UNION: either shape
SELECT DISTINCT ?thing WHERE {
{ ?thing a ex:Person } UNION { ?thing a ex:City }
}
Result: alice, bob, brisbane, hobart.
Shaping results
ORDER BY sorts, LIMIT and OFFSET page, DISTINCT collapses
duplicates:
SELECT DISTINCT ?name WHERE {
?person a ex:Person ;
ex:name ?name .
}
ORDER BY ?name
LIMIT 10
ASK: does anything match?
ASK returns yes/no instead of rows:
ASK WHERE { ?person ex:livesIn ex:brisbane }
CONSTRUCT builds new RDF from matches and DESCRIBE returns the
statements about one resource; both run against the same patterns.
Aggregates
GROUP BY with aggregate functions summarizes:
SELECT ?type (COUNT(?thing) AS ?count) WHERE {
?thing a ?type .
}
GROUP BY ?type
Result: ex:Person/2, ex:City/2.
Where queries run
-
The console workbench at
http://127.0.0.1:8080/— paste and run. -
waratah start --load-demo --query '…'— one-shot in the terminal. -
http://127.0.0.1:8080/rdf4j/repositories/main— the SPARQL endpoint for applications (see the HTTP reference).
Waratah’s documented deviations
A few SPARQL behaviors differ from the specification in deliberate,
documented ways — most notably, ordering comparisons across the
xsd:gYear family. The full list, and the --strict-sparql flag that
enforces spec-strict behavior, is in
Deviations from Spec.