![]() |
![]() |
![]() |
![]() |
SPARQL defines a query language for RDF data. How does a query language for graphs work? Naturally by providing a graph to be matched, it is conveniently called the "graph pattern".
To begin simple, the simplest query would consist of a triple with all 3 elements defined, e.g.:
1 |
ASK { <a> nie:title "Images" } |
Which would result in true
, as the triple does
exist. The ASK query syntax is actually the simplest form of graph
testing, resulting in a single boolean row/column containing whether
the provided graph exists in the store or not. It also works for more
complex graphs, for example:
1 2 3 4 5 |
ASK { <a> nie:title "Images" ; nmm:albumArtist <c> ; nmm:musicAlbum <b> . <b> nie:title "Go Off!" . <c> nmm:artistName "Jason Becker" } |
But of course the deal of a query language is being able to obtain the stored data. The SELECT query syntax is used for that, and variables are denoted with a '?' prefix, variables act as "placeholders" where any data will match and be available to the resultset or within the query as that variable name. The following query would be the opposite to the first ASK query:
1 |
SELECT * { ?subject ?predicate ?object } |
What does this query do? it provides a triple with 3 variables, that every known triple in the database will match. The '*' is a shortcut for all queried variables, the query could also be expressed as:
1 |
SELECT ?subject ?predicate ?object { ?subject ?predicate ?object } |
However, querying for all known data is most often hardly useful, this got unwieldly soon! Luckily, that is not necessarily the case, the variables may be used anywhere in the triple definition, with other triple elements consisting of literals you want to match for, e.g.:
Example 3.
Give me the title of resource <a>
(Result: "Images").
1 |
SELECT ?songName { <a> nie:title ?songName } |
Example 4. What is this text to <b>? (Result: the nie:title)
1 |
SELECT ?predicate { <b> ?predicate "Go Off!" } |
Example 5.
What is the resource URI of this fine musician? (Result: <d>
)
1 |
SELECT ?subject { ?subject nmm:artistName "Marty Friedman" } |
Example 6.
Give me all resources that are a music piece (Result: <a>
)
1 |
SELECT ?song { ?song a nmm:MusicPiece } |
And also combinations of them, for example:
Example 7.
Give me all predicate/object pairs for resource <a>
1 |
SELECT ?pred ?obj { <a> ?pred ?obj } |
Example 8. “The Answer to the Ultimate Question of Life, the Universe, and Everything”
1 |
SELECT ?subj ?pred { ?subj ?pred 42 } |
Example 9. Give me all resources that have a title, and their title.
1 |
SELECT ?subj ?obj { ?subj nie:title ?obj } |
And of course, the graph pattern can hold more complex triple
definitions, that will be matched as a whole across the stored
data. for example:
Example 10. Give me all songs from this fine album
1 2 |
SELECT ?song { ?album nie:title "Go Off!" . ?song nmm:musicAlbum ?album } |
Example 11. Give me all song resources, their title, and their album title
1 2 3 4 |
SELECT ?song ?songTitle ?albumTitle { ?song a nmm:MusicPiece ; nmm:musicAlbum ?album ; nie:title ?songTitle . ?album nie:title ?albumTitle } |
Stop a bit to think on the graph pattern expressed in the last query:
This pattern on one hand consists of specified data (eg. ?song must
be a nmm:MusicPiece
, it must have a
nmm:musicAlbum
and a nie:title
,
?album must have a nie:title
), which must all
apply for a match to happen.
On the other hand, the graph pattern contains a number of variables, some only used internally in the graph pattern, as a temporary variable of sorts (?album, in order to express the relation between ?song and its album title), while other variables are requested in the result set.