SPARQL Features and Extensions

Select Expressions

Arbitrary expressions can be used in the SELECT clause as in the following example:

tracker-sparql -q "SELECT (?p*(1-?discount)) AS ?price WHERE { ?s ns:price ?p ; ns:discount ?discount }"

Similar functionality is now in the SPARQL 1.1 draft. We will adapt the syntax used in tracker when the SPARQL Working Group decides on the final syntax.

Operators and Functions

Operators

Tracker supports the following operators as specified in SPARQL 1.0: BOUND, ISIRI, ISURI, STR, DATATYPE, REGEX, ||, &&, =, !=, !, +, -, *, /, <, <=, >, >=. It also supports the following operators as specified in SPARQL 1.1 draft: IN, NOT IN, IF.

Constructor Functions

Tracker supports the following constructor functions as specified in SPARQL 1.0:

xsd:string

xsd:integer

xsd:double

Constructor functions can be used to convert between primitive values.

XPath String Functions

Tracker supports the following functions as specified in XQuery 1.0 and XPath 2.0 Functions and Operators:

fn:concat(s1, s2, ...)

Concatenates two or more string arguments.

fn:string-join((s1, s2, ...), separator)

Returns the string produced by concatenating a sequence of strings using a separator. Separator is left out for NULL values.

fn:contains(haystack, needle)

Indicates whether haystack contains needle.

fn:starts-with(string, prefix)

Indicates whether the specified string begins with the specified prefix.

fn:ends-with(string, suffix)

Indicates whether the specified string ends with the specified suffix.

XPath Date and Time Functions

Tracker supports the following functions as specified in XQuery 1.0 and XPath 2.0 Functions and Operators:

fn:year-from-dateTime(datetime)

Returns the year in local time from a xsd:dateTime value.

fn:month-from-dateTime(datetime)

Returns the month in local time from a xsd:dateTime value.

fn:day-from-dateTime(datetime)

Returns the day in local time from a xsd:dateTime value.

fn:hours-from-dateTime(datetime)

Returns the hours in local time from a xsd:dateTime value.

fn:minutes-from-dateTime(datetime)

Returns the minutes in local time from a xsd:dateTime value.

fn:seconds-from-dateTime(datetime)

Returns the seconds in local time from a xsd:dateTime value.

fn:timezone-from-dateTime(datetime)

Returns the UTC offset in seconds from a xsd:dateTime value.

FTS (full-text search) Functions

fts:rank

This returns the score of the FTS match, the higher the better.

fts:offsets

This returns the URIs of the matching properties and the index of the matching word as a comma-separated string.

fts:snippet(urn)

Returns a snippet of the matched text. This function takes up to 4 optional arguments to respectively set match start text, match end text, ellipsis text, and approximate number of words to include as context. The default values for those are the equivalent to fts:snippet(?urn, '', '', '', 5)

  SELECT ?s fts:offsets(?s) fts:snippet(?s, '[', ']') WHERE {
      ?s fts:match 'hello' .
  } ORDER BY DESC (fts:rank(?s))

Tracker Functions

tracker:id

This function accepts a resource and returns the internal ID. Returns 1

  SELECT tracker:id (<http://www.w3.org/2001/XMLSchema#string>) { }

tracker:uri

This function accepts a ID and returns the resource. Returns xsd:string

  SELECT tracker:uri (1) { }

tracker:coalesce

This function accepts a variable number of arguments and returns the first bound value.

  SELECT tracker:coalesce (?full, ?nickname, 'none of the previous had value') WHERE {
      ?c a nco:IMContact .
      OPTIONAL { ?c nco:fullname ?full }
      OPTIONAL { ?c nco:nickname ?nickname }
  }

tracker:string-from-filename

This function sanitizes the filename passed as argument into a nicer string for displaying it to the user.

  SELECT tracker:string-from-filename(?filename) 
  WHERE { ... }

tracker:uri-is-descendant

Takes two uris, and return TRUE if the second uri can be considered a subdirectory of the first

  SELECT ?u WHERE {
      ?u a nmm:Photo .
      FILTER (tracker:uri-is-descendant ("file:///home/user/Photos", nie:url (?u)))
  }

Tracker Location Functions

tracker:cartesian-distance

The function calculates the cartesian distance between two points (lat1, lon1) and (lat2, lon2) within Pythagoran flat earth approximation.

  SELECT ?location xsd:integer(tracker:cartesian-distance(?lat1,?lat2,?lon1,?lon2))
  WHERE { ... }

tracker:haversine-distance

The function calculates the haversine distance between two points (lat1, lon1) and (lat2, lon2).

  SELECT ?location xsd:integer(tracker:haversine-distance(?lat1,?lat2,?lon1,?lon2))
  WHERE { ... }

In practice it is highly recommended that one uses bounding boxes (ie limit the ranges to sane values) to limit the number of points before using a distance based filter for filtering.

Property Functions

Tracker provides a SPARQL function for each property specified in an ontology. Each property function accepts exactly one subject as argument and returns the property value for that subject. Multiple values are returned as a concatenated string with comma-separated values.

tracker-sparql -q "SELECT nie:title(?song) WHERE { ?song a nmm:MusicPiece }"

Starting with Tracker 0.9.33, property functions accept two extra optional arguments. The first optional argument specifies the delimiter between multiple property values. It is ignored for single-valued properties and it defaults to comma.

If the second optional argument is present, the graph is returned in addition to the property value. The graph is separated from the property value by the delimiter specified in the argument.

Aggregate Functions

Tracker supports GROUP BY and the aggregate functions COUNT, SUM, AVG, MIN, MAX, and GROUP_CONCAT.

tracker-sparql -q "SELECT COUNT(?song) WHERE { ?song a nmm:MusicPiece }"

tracker-sparql -q "SELECT nie:title(?album) SUM(?duration) WHERE { ?song a nmm:MusicPiece ; nmm:musicAlbum ?album ; nmm:length ?duration } GROUP BY (?album)"

This is now in the SPARQL 1.1 draft. Tracker supports this as described in the draft except that it does not yet support HAVING clauses.

Subqueries

Tracker supports two kinds of subqueries in SPARQL: subqueries as graph patterns and subqueries as expressions.

Subqueries as Graph Patterns

Subqueries can be used as graph patterns by enclosing the query in curly braces. The subquery is evaluated only once and the results are joined with other graph patterns in the same way as regular group graph patterns. This is similar to how derived tables work in SQL.

This is now in the SPARQL 1.1 draft, although with an incorrect example.

Subqueries as Expressions

Subqueries can be used as expressions, for example, in the SELECT clause. Subqueries used as expressions must return in maximum one expression (one variable and zero or one solutions). These subqueries are usually evaluated more than once, for example, once per solution if the subquery is used in the SELECT clause. LIMIT 1 is commonly used in subqueries that would return more than one solution otherwise.

While this is being discussed in the SPARQL Working Group, this is not currently in any specification.

Named Graphs

Tracker has limited support for named graphs in SPARQL. Named graphs make it possible to associate a statement or a set of statements with a URI, which can be used to describe the origin of the statements. This provenance information can be useful in various situations such as synchronization or determination of responsibility.

While Tracker uses standard SPARQL syntax for the named graph support, it can only associate a single graph to a specific statement for technical reasons. This means that Tracker will only store the origin the first time a certain statement is inserted. If you insert the same statement a second time, the origin information will be ignored.

SPARQL Update inserting two statements with a named graph:

  INSERT {
      example:graphA a example:Graph ;
          example:graphTitle "Graph Foo" .
      GRAPH example:graphA {
          example:resource a example:A ;
          example:p 42
      }
  }

SPARQL query to retrieve provenance information about a specific statement:

  SELECT ?g ?title ?s WHERE {
      ?g a example:Graph ;
          example:graphTitle ?title
      GRAPH ?g {
          ?s example:p 42
      }
  }

Result of above query:

"http://example/graphA" "Graph Foo" "http://example/resource"

DELETE

The DELETE itself always affects all graphs. However, the WHERE pattern used with the DELETE supports graph matching the same way as it's supported for SELECTs.

SPARQL Update

SPARQL Update is specified in the http://www.w3.org/TR/sparql11-update/. Tracker only supports INSERT and DELETE operations with the default graph at the moment.

Documentation and examples about inserting data.

Attic/Tracker/Documentation/SparqlFeatures (last edited 2023-08-14 12:50:14 by CarlosGarnacho)